COMオブジェクトActiveDまたは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'の引数の少なくとも1つは、ランタイムマーシャラーによってマーシャリングできません。したがって、このような引数はポインターとして渡され、操作するには安全でないコードが必要になる場合があります。
観察:
- ActiveD(11警告)およびMSXML2(54警告)で発生します。
- 独自のCOMオブジェクトには表示されません。 .csprojファイルの
-
<Reference>
エントリに属性WrapperTool = "tlbimp"
が含まれています
- すべての警告にもかかわらず、実行中のシステムで問題は観察されていません。
警告を取り除く方法はありますか?
解決
のTLBIMPに関するMDSN記事のコメントによる2.0 、TLBIMPを自分で実行しないとこの問題を修正できません。
VSを使用して問題を再現するのは簡単でした。また、VSコメントプロンプトからTLBIMPを手動で実行して再現しました。
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への参照を追加してから、再度ビルドしました。 C ++プロジェクトを介した外部メイクファイルを使用するなど、他の方法でこれを行うことができます。これはPOCです。
MSBUILDとVSの面白い違いに注意してください。$(DevEnvDir)には末尾のバックスラッシュがありますが、MSBUILDにはありません。
他のヒント
同じ問題が発生したため、ここからの提案に従ってプロジェクトファイル(.csproj)を編集して修正しました:
各ビルド構成のプロパティグループに次のキーを追加しました:
<ResolveComReferenceSilent>True</ResolveComReferenceSilent>
次の方法で警告を停止できます。
#pragma warning disable warning-list #pragma warning restore warning-list
警告リストは、警告番号のコンマ区切りリストです。
この警告は、インポートしているtypelibにマネージコードに変換できないものが含まれているが、安全でないコードブロックでポインター操作を使用して処理できることを意味します。コードは.Net 1.1でも翻訳できませんでしたが、コンパイラは、警告するメソッドのいずれかを使用した場合に侵入する可能性のあるトラップについて警告するほどスマートではありませんでした。