0

I have a c# solution that makes use of a cpp COM object. Both the COM object and the c# application are specifically built for a 64-bit system. When I run from VS 2010, the solution works properly. However, after I install it on a different system (64 bit), the COM object is not found.

I figured this was because it didn't get registered during the install, but I seem to be having trouble doing that. When I try

regsvr32 ComObject.dll

I get an error stating that "The module 'ComObject.dll' failed to load. Make sure the binary is stored at the specified path or debug it to check for problems with the binary or dependent .DLL file.

I am calling regsvr32 from the directory the dll resides in, and I triple-checked that the name was typed correctly. I tried registering it in the installer, setting the dll Register switch to vsdrfCOM, and got the warning "Unable to create registration information for file named 'ComObject.dll'. Most likely this is because the dll was built in a separate solution and added to this solution as a resource.

Consequently, I can install it on my dev system, and it runs fine. I assume this is because VS already registered the dll. (currently, the dll is not a part of the installer as it was causing problems, so I copied the one in the debug folder.

Does anyone have any ideas what I might be doing wrong?

Additional Information:

Based on instructions from David Heffernan, I ran Dependency Walker the correct way. Below are the last couple lines before I get the error saying "entry-point DllRegisterServer was not found."

...
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.

After pressing OK, I get:

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).

There is no specific error message outside of the mention of DllRegisterServer. I did run as administrator. While running, I got an additional error in the module list: Error opening file. The system cannot find the path specified. That makes sense since it is an empty string. This has a questionmark next to it, so I assume it is delay-load.

I ran Dependency Walker again on regsvr32.exe, and got the following error:

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

I also found these errors at the top of the log file:

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.

Thank you all for your help.

5
  • It is possible that the COM object is missing some dependencies? I know a COM server will not register is dependencies are missing. Commented Mar 8, 2013 at 0:00
  • @RobGoodwin - I used Dependency Walker on it, and it is missing IESHIMS.dll, but my understanding is that this is an optional dll that is not needed if the appropriate error handling is present. I did not develop the cpp code, but have access to it. If I do need to make sure it is included in the dll, how would I add it, and why would the dll run without it? My cpp skills are very basic. Commented Mar 8, 2013 at 0:08
  • Try a Release build of said-same DLL. Odds are you debug build is dependent on MSVCRTD.DLL, MSVCPD.DLL, etc, none of which are on a clean machine. The right VC runtime redist package plus a Release-build of your DLL will likely eliminate a major dependency issue. Commented Mar 8, 2013 at 0:40
  • @WhozCraig - Thank you for the reply. The Com Object is a release build. It is working when accessed from VS, so I know it is possible to register (or whatever VS does to it so it works). According to Dependency Walker, IESHIMS.DLL is missing from the dll, but I'm not sure how to add it. Commented Mar 8, 2013 at 0:45
  • 1
    First ensure the correct regsvr32.exe is being used. the IESHIMS.DLL dependency (and a few others) are usually red herrings because they're delay-load targets (don't ask). Is there anything your DLL uses that is not strictly provided by the C runtime and/or the WIN32 API natively? I'd starts with those. Commented Mar 8, 2013 at 0:50

3 Answers 3

1

It's likely a dependency problem. Solve it with Dependency Walker. Use the Profile menu to start a process. Run regsvr32. Specify the command line arguments and the working directory.

My guess is that the problem is a missing MSVC runtime, but the tool will reveal what is causing the failure.

You'll need to run Dependency Walker elevated so that the registration can work.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for your reply. I did find that IESHIMS.DLL cannot be found, but am not quite sure how to add it to the dll. I've got minimal experience with cpp projects. My main confusion is how come VS can register the dll, but I cannot manually?
IESHIMS is not relevant. It's an optional delay load dll. But I don't think you understand my answer. You have not run in profile mode.
Before working on this, I have not used Dependency Walker before, so I'm still getting up to speed on what needs to be done and how to interpret the results. When I click on Profile, I have the option to start and stop profiling, but they are both grayed out.
You have to load the executable first. In this case it is regsvr32.
I did this, and found an error at the top saying modules with different CPU types were found. I do compile this as x64, but I have no way of checking if all the dependent libraries are x64. Could this be the problem?
|
0

Often Windows gets confused about whether it should run an application from the System32 or the SysWOW64 directory.

Try explicitly running the 64-bit version of regsvr32:

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

1 Comment

That won't run 64 bit regsvr32. That runs the one with the same bitness as the command prompt. Because of the file redirector. So that will run 32 bit from 32 bit cmd.exe. The code in this answer is identical to that in the Q. And if it was bitness, the error would be different.
0

Thank you to David Hefferman and WhozCraig; your information helped me get started with Dependency Walker, which I can see will prove to be a powerful tool after I figure out how to interpret what it finds. It also helped me track down possible problems.

In the end, I wound up going in a different direction. I added the cpp project to my main project, and then used the output in my installer. This caused it to register correctly. I'm still not sure how this is different from running regsvr32, but whatever the difference is, it caused things to start working.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.