访问COM对象

时间:2013-03-07 23:54:35

标签: c# c++ visual-studio-2010 com

我有一个使用cpp COM对象的c#解决方案。 COM对象和c#应用程序都是专为64位系统构建的。当我从VS 2010运行时,解决方案正常运行。但是,在我将其安装在另一个系统(64位)上后,找不到COM对象。

我认为这是因为它在安装过程中没有注册,但我似乎无法做到这一点。当我尝试

regsvr32 ComObject.dll

我收到一条错误,指出“模块'ComObject.dll'无法加载。确保二进制文件存储在指定的路径中或调试它以检查二进制文件或从属.DLL文件的问题。

我从dll所在的目录中调用regsvr32,并且我三重检查了该名称的输入是否正确。我尝试在安装程序中注册它,将dll Register开关设置为vsdrfCOM,并收到警告“无法为名为'ComObject.dll'的文件创建注册信息。很可能这是因为dll是在单独的解决方案中构建的并且已添加以此资源作为解决方案。

因此,我可以在我的开发系统上安装它,它运行正常。我认为这是因为VS已经注册了dll。 (目前,dll不是安装程序的一部分,因为它导致了问题,所以我复制了调试文件夹中的那个。

有没有人有任何想法我可能做错了什么?

其他信息:

根据David Heffernan的指示,我以正确的方式运行了Dependency Walker。下面是我收到错误之前的最后几行,说“找不到入口点DllRegisterServer。”

...
GetProcAddress(0x000007FEFCBB0000 [UXTHEME.DLL], "DrawThemeText") called from "COMCTL32.DLL" at address 0x000007FEFCC2FD99 and returned 0x000007FEFCBB61F8.
GetProcAddress(0x000007FEFCBB0000 [UXTHEME.DLL], "EndBufferedAnimation") called from "COMCTL32.DLL" at address 0x000007FEFCC2FD99 and returned 0x000007FEFCBB4F98.
GetProcAddress(0x000007FEFCBB0000 [UXTHEME.DLL], "GetBufferedPaintDC") called from "DUSER.DLL" at address 0x000007FEFC58069D and returned 0x000007FEFCBC0BC0.
GetProcAddress(0x000007FEFCBB0000 [UXTHEME.DLL], "GetBufferedPaintTargetDC") called from "DUSER.DLL" at address 0x000007FEFC58069D and returned 0x000007FEFCBC0B5C.
GetProcAddress(0x000007FEFCBB0000 [UXTHEME.DLL], "EndBufferedPaint") called from "DUSER.DLL" at address 0x000007FEFC58069D and returned 0x000007FEFCBB4F98.
GetProcAddress(0x000007FEFC570000 [DUSER.DLL], "FindGadgetFromPoint") called from "COMCTL32.DLL" at address 0x000007FEFCC2FD99 and returned 0x000007FEFC581F40.
GetProcAddress(0x000007FEFC570000 [DUSER.DLL], "ForwardGadgetMessage") called from "COMCTL32.DLL" at address 0x000007FEFCC2FD99 and returned 0x000007FEFC582CAC.

按OK后,我得到:

LoadLibraryW("comctl32.dll") called from "USER32.DLL" at address 0x00000000779A91DC.
LoadLibraryW("comctl32.dll") returned 0x000007FEFCC10000.
GetProcAddress(0x000007FEFCC10000 [COMCTL32.DLL], "RegisterClassNameW") called from "USER32.DLL" at address 0x00000000779A91F9 and returned 0x000007FEFCC38024.
GetProcAddress(0x000007FEFCBB0000 [UXTHEME.DLL], "BufferedPaintStopAllAnimations") called from "COMCTL32.DLL" at address 0x000007FEFCC2FD99 and returned 0x000007FEFCBCE408.
GetProcAddress(0x000007FEFCBB0000 [UXTHEME.DLL], "BufferedPaintUnInit") called from "COMCTL32.DLL" at address 0x000007FEFCC2FD99 and returned 0x000007FEFCBBFA04.
GetProcAddress(0x000007FEFC570000 [DUSER.DLL], "DisableContainerHwnd") called from "COMCTL32.DLL" at address 0x000007FEFCC2FD99 and returned 0x000007FEFC57A38C.
GetProcAddress(0x000007FEFCBB0000 [UXTHEME.DLL], "BufferedPaintUnInit") called from "DUSER.DLL" at address 0x000007FEFC58069D and returned 0x000007FEFCBBFA04.
GetProcAddress(0x000007FEFC570000 [DUSER.DLL], "DUserFlushMessages") called from "COMCTL32.DLL" at address 0x000007FEFCC2FD99 and returned 0x000007FEFC57A8A0.
GetProcAddress(0x000007FEFC570000 [DUSER.DLL], "DUserFlushDeferredMessages") called from "COMCTL32.DLL" at address 0x000007FEFCC2FD99 and returned 0x000007FEFC57A830.
GetProcAddress(0x000007FEFC570000 [DUSER.DLL], "DeleteHandle") called from "COMCTL32.DLL" at address 0x000007FEFCC2FD99 and returned 0x000007FEFC574BB8.
GetProcAddress(0x00000000779A0000 [USER32.DLL], "UnregisterMessagePumpHook") called from "DUSER.DLL" at address 0x000007FEFC57B8A9 and returned 0x00000000779A8564.
DllMain(0x0000000180000000, DLL_PROCESS_DETACH, 0x0000000000000000) in "MAPIEX64.DLL" called.
DllMain(0x0000000180000000, DLL_PROCESS_DETACH, 0x0000000000000000) in "MAPIEX64.DLL" returned 1 (0x1).
DllMain(0x000007FEFB5F0000, DLL_PROCESS_DETACH, 0x0000000000000000) in "MAPI32.DLL" called.
DllMain(0x000007FEFB5F0000, DLL_PROCESS_DETACH, 0x0000000000000000) in "MAPI32.DLL" returned 1 (0x1).
DllMain(0x0000000051AF0000, DLL_PROCESS_DETACH, 0x0000000000000000) in "MFC100.DLL" called.
DllMain(0x0000000051AF0000, DLL_PROCESS_DETACH, 0x0000000000000000) in "MFC100.DLL" returned 1 (0x1).
DllMain(0x000007FEF9E60000, DLL_PROCESS_DETACH, 0x0000000000000000) in "MSIMG32.DLL" called.
...
Exited "REGSVR32.EXE" (process 0x23A0) with code 4 (0x4).

在提及DllRegisterServer之外没有特定的错误消息。我确实以管理员身份运行。运行时,我在模块列表中出现了一个额外的错误:打开文件时出错。该系统找不到指定的路径。这是有道理的,因为它是一个空字符串。它旁边有一个问号,所以我认为它是延迟加载。

我在regsvr32.exe上再次运行了Dependency Walker,并收到以下错误:

LoadLibraryExW("C:\Program Files\Project\ComObject.dll", 0x0000000000000000, LOAD_WITH_ALTERED_SEARCH_PATH) returned NULL. Error: The specified module could not be found (126).

我还在日志文件的顶部发现了这些错误:

Error: Modules with different CPU types were found.
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.

谢谢大家的帮助。

3 个答案:

答案 0 :(得分:1)

这可能是一个依赖问题。用Dependency Walker解决它。使用“配置文件”菜单启动进程。运行regsvr32。指定命令行参数和工作目录。

我的猜测是问题是缺少MSVC运行时,但该工具将揭示导致失败的原因。

您需要运行Dependency Walker,以便注册可以正常工作。

答案 1 :(得分:0)

Windows经常会对是否应该从System32SysWOW64目录运行应用程序感到困惑。

尝试显式运行64位版本的regsvr32

%SystemRoot%\System32\regsvr32.exe ComObject.dll

答案 2 :(得分:0)

感谢David Hefferman和WhozCraig;您的信息帮助我开始使用Dependency Walker,在我弄清楚如何解释它找到的内容后,我可以看到它将被证明是一个强大的工具。它还帮助我找出可能存在的问题。

最后,我走向了另一个方向。我将cpp项目添加到我的主项目中,然后在我的安装程序中使用输出。这导致它正确注册。我还不确定这与运行regsvr32有什么不同,但无论有什么不同,它都会让事情开始起作用。