0

私の C# アプリケーションは、サードパーティの C# COM dll を使用します。その dll のすべてのメンバーを最も美しい方法で呼び出したいと思います。たとえば、この dll をプロジェクト参照と " using " ステートメントに追加した後などです。しかし、反対側から、システムにdllが存在しないかどうかを判断し、アプリケーションから例外を表示したい(遅延バインディングを使用できるように)。では、dll missing をキャッチするにはどうすればよいでしょうか。この dll を使用すると、VisualStudio はこの dll のすべてのタイプをusingステートメントの後に好きになりますか?

Com dll は regasm.exe を使用して登録しています。このツールは、dll から .tlb ファイルも生成します。この .tlb をどうにか使えないでしょうか。

4

2 に答える 2

1

Visual Studio は、いわゆる Interop-Library を生成します。これは、 と呼ばれるライブラリを参照している場合、 と呼ばれるMyCOMLib.dllアセンブリが生成されることを意味しますMyComLib.Interop.dll。このアセンブリには、.NET アプリケーションからインスタンス化する .NET ラッパー オブジェクト (いわゆるRuntime Callable Wrappers ) が含まれます。TlbImp.exeツールを使用して、この相互運用ライブラリを独自に生成できます。

したがって、実際にインスタンス化しているのは、実際の COM オブジェクトではなく、それらの COM オブジェクトのある種のプロキシとして機能する .NET オブジェクトです。内部的には、CoCreateInstanceまたはCoCreateInstanceExCOM クラス ファクトリを呼び出しています。また、これらのオブジェクトのメモリ処理も管理します。( を使用してこの管理に影響を与えることができますが、これは危険な場合があることに注意してMarshal.ReleaseComObjectください)。

これは、アプリケーションが常にこれらの相互運用アセンブリと共に出荷されることを意味します。これらのアセンブリが存在しない場合 (およびProject Referencesを使用してそれらを参照した場合)、アプリケーションは実行されません (起動時に例外がスローされます)。アセンブリをアプリケーションのAppDomainにロードできる場合、interop タイプのオブジェクトを作成するまで問題はありません。RCW はCoCreateInstance/CoCreateInstanceExを CLSID と共に呼び出します (相互運用アセンブリは TlbImp.exe ツールによって認識されます)。これらのクラス ID がレジストリ内に見つからない場合、アプリケーションは実行時例外をスローします。

ライブラリが存在するかどうかを確認する良い方法は、アプリケーションのセットアップ中に一意のライブラリ ID とバージョンを確認することです。それらはレジストリ内に保存されます。ライブラリの GUID とバージョンを知る必要がありますHKLM\Software\Classes\TypeLib\{Guid}\{Version}

最良の方法は、ライブラリを単独でインストールするサード パーティの再頒布可能パッケージと一緒にアプリケーションを配布することです。これにより、他のアプリケーションがサード パーティのタイプ ライブラリを削除しないようにすることもできます。これは、Microsoft が Visual C++ ライブラリまたは DirectX で行っている方法です。

于 2012-12-04T10:21:06.537 に答える
1

これを行う最善の方法は、progID から COM オブジェクトを取得して作成することだと思います。

Type comType = Type.GetTypeFromProgID(progID);
if (comType == null)
  throw new Exception("COM object not found!);
dynamic comObject = Activbator.CreateInstance(comType);
comObject.SomeOperation();

このソリューションの付加価値は、アプリケーションの 1 つのバージョンが x86 と x64 の両方の COM オブジェクトで動作するため、OS のバージョンは関係ありません。

于 2012-12-04T10:22:13.080 に答える