Type.GetTypeFromCLSID和Type.GetTypeFromProgID获取缓存结果?

时间:2016-12-12 12:44:06

标签: c# .net reflection com interop

我的程序使用来自第三方的COM驱动程序。 我正在尝试实现不同驱动程序版本之间的切换。

首先,我尝试使用VS生成的Interop dll并从代码中调用regsvr32。我能够通过Assembly.Load和反射调用驱动程序,但似乎尽管事实上我调用了不同的Interop库,但我得到了相同的版本。我尝试在调用interops之前通过regsvr32注册和取消注册库,并尝试在regsvr32运行缓慢的情况下进行延迟。

最后我删除了互操作库,并决定直接使用COM。 两个版本的驱动程序都具有相同的CLSID。我最终得到的代码只是尝试实例化一个COM对象并获得一个获取版本值的属性。

while (true)
        {
            var CLSID = new Guid("E4795281-3564-11D4-8E97-0080C87C930A");
            var type = Type.GetTypeFromCLSID(CLSID);
            var obj = Activator.CreateInstance(type);
            object propertyValue = type.InvokeMember("Version", System.Reflection.BindingFlags.GetProperty, null, obj, null);
            Console.WriteLine(propertyValue);
            Console.ReadKey();
        }

我运行程序,然后尝试手动注册dll。无论我在注册后等待多久,我的程序都会实例化它在开始时获得的版本。如果我重新启动程序 - 它将获得最后一个注册版本。我看到注册表记录发生了变化,所以我认为可能存在一些缓存问题。

我尝试在单独的AppDomain中运行代码并重新创建它,但它没有帮助。

我也尝试使用Type.GetTypeFromProgID,结果相同。

有关解决方法的任何建议吗?

1 个答案:

答案 0 :(得分:0)

尝试Reg Free COM,我记得在某个地方阅读它有利于处理多个版本并避免冲突。

我假设你是VS.回到正常的Interop。将COM引用添加到项目中以自动生成互操作接口。然后右键单击互操作引用并设置Isolated = True。确保此时在注册表中注册了COM。 现在编译你的程序。您应该看到输出文件夹中生成的.manifest文件以及.exe。在记事本中打开清单,希望它上面列出了所有各种CLSID和TLIB的dll。 从注册表中注销所有COM(使用Regsvr32)。

现在运行该应用程序。 在此模式下,激活上下文将查询.manifest以查找所有必需的资源而不是注册表,并希望它应该允许正确调用每个dll版本。