0

我的 C# 应用程序将使用第三方 C# COM dll。我想以最漂亮的方式调用该 dll 的所有成员 - 就​​像在将此 dll 添加到项目引用和“ using ”语句之后。但从另一面来看,我想确定系统中是否不存在 dll 并从我的应用程序中显示异常(就像我可以使用后期绑定一样)。那么我怎样才能捕获 dll missing ,并使用这个 dll,VisualStudio 会在using语句后看到所有类型的这个 dll 喜欢呢?

Com dll 正在使用 regasm.exe 进行注册。该工具还可以从 dll 生成 .tlb 文件。也许我可以以某种方式使用这个 .tlb ?

4

2 回答 2

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();

此解决方案的附加价值是您的应用程序的一个版本将同时使用 x86 和 x64 COM 对象,因此操作系统版本无关紧要。

于 2012-12-04T10:22:13.080 回答
1

Visual Studio 会为您生成一个所谓的互操作库。这意味着如果您引用一个被调用的库,MyCOMLib.dll它将生成一个名为MyComLib.Interop.dll. 此程序集包含您从 .NET 应用程序实例化的.NET 包装器对象(所谓的Runtime Callable Wrappers )。您可以使用TlbImp.exe -Tool 自行生成此互操作库。

因此,您实际实例化的不是实际的 COM 对象,而是充当这些 COM 对象的某种代理的 .NET 对象。在内部,他们正在为您调用CoCreateInstanceorCoCreateInstanceEx和 COM 类工厂。他们还管理这些对象的内存处理。(您可以使用 来影响此管理Marshal.ReleaseComObject,但您应该注意到这可能很危险)。

这意味着您的应用程序总是与这些互操作程序集一起发布。如果这些程序集不存在(并且您已使用Project References引用了它们),则应用程序将不会运行(它将在启动时引发异常)。如果程序集可以加载到您应用程序的AppDomain中,则在您创建互操作类型对象之前不会有任何问题。RCW 将CoCreateInstance/CoCreateInstanceEx与 CLSID 一起调用(互操作程序集通过 TlbImp.exe 工具知道这一点)。如果在注册表中找不到这些类 ID,您的应用程序将引发运行时异常。

检查库是否存在的一个好方法是在应用程序设置期间检查唯一的库 ID 和版本。这些存储在注册表中。您需要知道库的 GUID 和版本,然后您会在HKLM\Software\Classes\TypeLib\{Guid}\{Version}.

最好的方法是将您的应用程序与自行安装库的第 3 方可再发行包一起交付。这也确保了其他应用程序不会删除第 3 方类型库。这就是微软使用 Visual C++ 库或 DirectX 的方式。

于 2012-12-04T10:21:06.537 回答