【问题标题】:Dynamically refer to COM dll using C#使用 C# 动态引用 COM dll
【发布时间】:2012-12-04 19:00:27
【问题描述】:

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

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

【问题讨论】:

    标签: c# .net dll com


    【解决方案1】:

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

    因此,您实际实例化的不是实际的 COM 对象,而是充当这些 COM 对象的某种代理的 .NET 对象。在内部,他们正在为您调用 @987654322@@987654323@ 和 COM 类工厂。他们还管理这些对象的内存处理。 (您可以使用@987654324@ 对此管理施加影响,但您应该使用notice that this can be dangerous

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

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

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

    【讨论】:

    • 感谢您的工作,这解释了很多,但我在这里看不到答案。我也知道所有 dll 都必须与应用程序一起安装,但它可以在利用期间被删除,我的应用程序必须确定并显示有关它的消息。
    • 然后您可以在某种引导程序中为您的应用程序检查注册表项。但是为什么用户应该删除库而不是使用它的(您的)应用程序?
    【解决方案2】:

    我认为最好的方法是从 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 对象,因此操作系统版本无关紧要。

    【讨论】:

    • 但我希望我的 VS intellisense 看到所有类型的 dll
    • COM 对象只有一个类型 - 如果您需要更多类型,那么每种类型都应该有自己的 ProgID。
    猜你喜欢
    • 1970-01-01
    • 2014-07-07
    • 2020-09-10
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    相关资源
    最近更新 更多