加载从COM进程id .NET程序集,而无需创建一个COM对象创建一个、进程、加载、对象

2023-09-04 05:16:21 作者:烟酒为伴

一个奇怪的问题了一下,大概落后的大多数人想做的事,但我试图解决一个传统的COM问题。

A bit of an odd question and probably backwards from what most people want to do, but I'm trying to work around a legacy COM issue.

我有两个组成部分,这两者都是实际上.NET组件,但由于历史的原因之一加载其他作为COM对象(该组件注册为COM互操作)。这是一个插件架构,其中插件是由它的COM进程id识别,所以这是唯一的一条信息,我得到加载插件组装。

I have two components, both of which are actually .NET assemblies, but for historical reasons one is loading the other as a COM object (the assembly is registered for COM Interop). It's a plug-in architecture where the plug-in is identified by its COM ProgID, so that's the only piece of information I get to load the plug-in assembly.

一种方法我试过是:

var objType = Type.GetTypeFromProgID("My.ProgId");
var objLateBound = Activator.CreateInstance(objType);
IMyInterface netAssembly;
try
    {
    netAssembly = (IMyAssembly)objLateBound;
    }
catch (Exception)
    {
    netAssembly = null;
    }

如果要转换成.NET接口成功,我知道我有一个.NET程序集,并可以通过接口来访问它。然而,该技术是一个有点笨拙,我得到问题的东西尤其是在64位系统中的COM端。我宁愿只消除加载COM对象,如果可能的话直接加载插件作为.NET程序集。

If the cast to a .NET interface succeeds, the I know I have a .NET assembly and can access it through the interface. However, the technique is a bit clumsy and I'm getting problems with the COM side of things especially on 64-bit systems. I'd rather just eliminate loading the COM object and load the plug-in directly as a .NET assembly, if possible.

但唯一的一块我得走了上信息是插件的COM进程id。

But the only piece of information I've got to go on is the plug-in's COM ProgID.

所以,我怎么能去从一个COM进程id来加载.NET程序集的不会造成任何COM对象的?

So, how can I go from a COM ProgID to loading a .NET Assembly, without creating any COM objects?

推荐答案

查找在注册表中找到的ProgID您有相关的DLL。一旦你拥有了它的完整路径,负荷它作为一个正常的.NET程序集

Look up in the registry to find the DLL associated with the ProgID you have. Once you have its full path, load it as a normal .NET assembly:

var type = Type.GetTypeFromProgID("My.ProgId", true);
var regPath = string.Format(@"{0}\CLSID\{1:B}\InProcServer32", 
    Registry.ClassesRoot, type.GUID);
var assemblyPath = Registry.GetValue(regPath, "", null);
if (!string.IsNullOrEmpty(assemblyPath))
{
    var assembly = Assembly.LoadFrom(assemblyPath);
    // Use it as a normal .NET assembly
}