C# 无法在windows 7 x64上正确注册x64 COM dll 我有一个C++的ATL COM DLL,最初是为x86构建的,DLL被为X86构建的.NET 4应用程序消耗,所有的工作都很好。
重新编译x64的COM dll,然后使用C# 无法在windows 7 x64上正确注册x64 COM dll 我有一个C++的ATL COM DLL,最初是为x86构建的,DLL被为X86构建的.NET 4应用程序消耗,所有的工作都很好。,c#,.net,visual-studio,visual-c++,com,C#,.net,Visual Studio,Visual C++,Com,重新编译x64的COM dll,然后使用c:\windows\system32\regsvr32注册它(取消注册x86 dll后),我无法在Visual Studio添加参考窗口中看到COM dll,我使用x64导出HKCR和HKLM\软件的注册密钥,然后注册dll的x86版本,并且没有丢失任何密钥,相应的键指向正确的dll位置 此外,在注册x64 dll后,我可以通过导航到文件所在的文件夹并选择它来添加对dll的引用,但它仍然无法执行(.net assembly设置为x64),并出现以下错误
c:\windows\system32\regsvr32
注册它(取消注册x86 dll后),我无法在Visual Studio添加参考窗口中看到COM dll,我使用x64导出HKCR和HKLM\软件的注册密钥,然后注册dll的x86版本,并且没有丢失任何密钥,相应的键指向正确的dll位置
此外,在注册x64 dll后,我可以通过导航到文件所在的文件夹并选择它来添加对dll的引用,但它仍然无法执行(.net assembly设置为x64),并出现以下错误
System.Runtime.InteropServices.COMException(0x80040154):正在检索
具有CLSID的组件的COM类工厂
{00000000-0000-0000-0000-A797AD238051}由于以下原因失败
错误:80040154类未注册(HRESULT异常:
0x80040154(REGDB_E_CLASS NOTREG))。在
System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔值
publicOnly、Boolea n noCheck、Boolean&canBeCached、,
RuntimeMethodHandleInternal&ctor、Boolean&bNeedSecurity检查)位于
System.RuntimeType.CreateInstanceSlow(布尔publicOnly,布尔型
skipCheckThis,Boo lean fillCache)在
System.RuntimeType.CreateInstanceDefaultCtor(仅限布尔值),
布尔skipVisibil ITY检查,布尔skipCheckThis,布尔
在System.Activator.CreateInstance(类型,布尔值)处
(非公开)
我花了相当多的时间在网上搜索,但没有找到任何远程接近的东西,没有人看到类似的东西,或者任何我可以使用的调试工具
顺便说一句,我不拥有这个dll,拥有它的人可以看到机器上构建的x64 dll,但已经在另外两台机器上试用过,但在任何一台机器上都不起作用。这个问题很老了,我需要更多信息来全面排除故障。不过,我可能可以为遇到相同问题的任何人提供一些提示 假设您使用的是
regsvr32
,则DLL使用的是一种称为。这意味着DLL正在一个名为的导出函数中处理自己添加到Windows注册表的操作。您似乎已经发现,x86和x64之间的注册表项有所不同,但这不一定是您的核心问题。您可以而且通常应该同时注册x86和x64类型库
检查特定类型库如何注册的一种方式是工具。注册表中也有相同的信息,但是这个工具可以更友好一些。该工具应位于从Visual Studio命令提示符设置的路径中。这听起来像是关于一个具有给定GUID的类的错误,您可以从对象类->树中的所有对象中进行检查:
如果您碰巧拥有该类(您可能需要重新注册x86版本以进行检查),则可以通过展开刚找到的GUID条目来查找该类实现的COM接口的信息。如果有类型库,它应该这样说。请注意,TypeLib信息中的路径既可以有win32
项,也可以有win64
项:
如果没有进一步的信息,很难说,但我猜x64的自注册和/或类型库有问题。顺便说一句,对于您计划发布的库,您可能无论如何都不依赖于自注册——安装程序包可以而且应该自己创建注册表项。如果您有更多信息,我可以尝试提供更多细节。在对话框中看不到组件是完全正常的,VS是一个32位进程,因此只能看到32位COM服务器。不要注销x86版本。x64的一个挑战是它的帮助,有时太多了。有可能一个注册正在践踏另一个注册。对于许多情况,SysInternals是一个很好的工具。在重现问题的同时监视注册表,您可以看到真正正在读取的注册表项。我还建议您通过消除互操作服务来简化事情。在C++中构建简单的32位和64位测试客户端。在尝试从托管代码调用COM对象之前,先让它们工作。@FrankBoyne我给procmon一个机会,没想到,谢谢你的帮助suggestion@HansPassant我不确定行为是否正常,我对COM经验不太丰富,但是我确实在XS中添加了一个测试x64 C++ + COM DLL,并在VS的添加参考窗口中看到它。还可以在我的x64.NET应用程序中调用它。另外,x64和x86具有相同的typelib和clsid guid,如果我不注销x86库,这不会导致问题吗?我确实尝试过这种方法,但我得到了AccessViolationException,甚至没有多线程处理任何东西,但当然dll在dll开发人员的机器上工作得很好