Множество предупреждений о сборке при ссылках на COM-объекты ActiveDs или MSXML2
-
06-07-2019 - |
Вопрос
После переноса проекта с .NET 1.1 на .NET 2.0 MSBuild выдает множество предупреждений для некоторых COM-объектов.
Пример кода для тестирования (фактический код не имеет значения, просто используется для создания предупреждений):
using System;
using System.DirectoryServices;
using ActiveDs;
namespace Test
{
public class Class1
{
public static void Main(string[] args)
{
string adsPath = String.Format("WinNT://{0}/{1}", args[0], args[1]);
DirectoryEntry localuser = new DirectoryEntry(adsPath);
IADsUser pUser = (IADsUser) localuser.NativeObject;
Console.WriteLine("User = {0}", pUser.ADsPath);
}
}
}
Предупреждающие сообщения выглядят следующим образом
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets :предупреждение :По крайней мере, один из аргументов для 'ITypeLib.RemoteGetLibAttr' не может быть маршалирован маршалером среды выполнения.Следовательно, такие аргументы будут передаваться как указатель, и для манипулирования ими может потребоваться небезопасный код.
Наблюдения:
- Происходит для ActiveDs (11 предупреждений) и MSXML2 (54 предупреждения).
- Не замечено для наших собственных COM-объектов.
<Reference>
запись в файле .csproj содержит атрибутWrapperTool = "tlbimp"
- Несмотря на все предупреждения, никаких проблем в запущенной системе замечено не было.
Есть идеи, как избавиться от предупреждений?
Решение
Согласно комментарию в Статья MDSN о TLBIMP для версии 2.0, вы не можете решить эту проблему без самостоятельного запуска TLBIMP.
Было легко воспроизвести вашу проблему с помощью VS.Я также воспроизвел его, запустив TLBIMP вручную из командной строки VS comment:
tlbimp c:\WINNT\system32\activeds.tlb /out:interop.activeds.dll
Исправление состояло в том, чтобы использовать переключатель / silent
tlbimp c:\WINNT\system32\activeds.tlb /silent /out:interop.activeds.dll
Как указано в комментарии к статье MSDN, ссылка COM становится ссылкой на сборку .net на сборку взаимодействия, которую вы создали самостоятельно.
Я не эксперт по VS, но я выполнил эту работу, добавив предварительную сборку к проекту:
"$(DevEnvDir)\..\..\SDK\v2.0\bin\tlbimp" c:\WINNT\system32\activeds.tlb
/namespace:ActiveDs /silent /out:"$(ProjectDir)interop.activeds.dll"
Создал его один раз, чтобы у меня была библиотека dll для добавления ссылки на вкладку обзор.Добавлена ссылка на interop.activeds.dll в корне моего проекта, а затем собрана заново.Возможно, вы захотите сделать это каким-либо другим способом, например, с помощью внешнего make-файла через проект C ++.Это больше похоже на POC.
Обратите внимание на забавную разницу в MSBUILD vs VS, $ (DevEnvDir) имеет завершающую обратную косую черту, а MSBUILD - нет.
Другие советы
Я столкнулся с той же проблемой и исправил ее, отредактировав файл проекта (.csproj), следуя предложению отсюда:
Я добавил следующий ключ в группу свойств каждой конфигурации сборки:
<ResolveComReferenceSilent>True</ResolveComReferenceSilent>
Вы можете остановить предупреждения с помощью:
#pragma warning disable warning-list #pragma warning restore warning-list
где список предупреждений - это разделенный запятыми список номеров предупреждений.
Предупреждение означает, что импортируемый вами typelib содержит что-то непереводимое в управляемый код, но с ним можно справиться с помощью операций с указателями в небезопасном блоке кода.Код был непереводимым и в .Net 1.1, но компилятор был недостаточно умен, чтобы предупредить вас о ловушке, в которую вы можете попасть, если воспользуетесь одним из методов, о которых он вас предупреждает.