10

I have a 32 bit .Net application winform that invokes a C++ dll. We package the app into an installer and it installs and runs fine on at least 20 or so machines. The app was originally developed and runs fine on a Win 7 x64 machine (mine).

However when I run it on my bosses desktop (Win 7 x64) the application will not launch. oh yeah...

When I try to launch the application I get a JIT dialog with

System.IO.FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)

When I run depends on the exe on the bosses machine it says that app exe is x86 but that all the dependent dll at x64 and flags it as an error. When I run depends on the app on my machine the exe and dll are all marked x86.

How could this change between machines? The installer is just unpacking and copying in the normal way and works fine on plenty of other x64 machines...

naturally it only breaks on his machine which is two hours away and we have a trade show coming up. sigh. very confused...

================= solved ==================

So we fixed it. Finding the missing the dll was a bit tricky.

First of all we goofed and we ran the wrong version of depends for an x64 box. So it was incorrectly reporting that the app was looking for x64 dll. If we had run the correct version I think we would have caught the issue sooner.

What solved it for us was looking at the log of Process Monitor from System Internals. It logs every file access and registry read. The log quickly showed a failed read on a Direct X 11 dll.

It turns out that a previous installer from some other app had installed some of the DX11 dll. That fooled our installer, and it skipped the DirectX 11 step so we had a missing dll.

Thanks for the help guys!

meissnersd
  • 1,272
  • 2
  • 12
  • 21
  • It would be easier to help you if you provided more details about the DLL's that try to load as x64. Are they .NET assemblies, your own C++ DLL, or system DLL's? Also, are you running the x86 or the x64 version of Dependency Walker? – Martin Liversage Nov 20 '12 at 10:47
  • 1
    I suspect there is a 32 bit and 64 bit version of that DLL with the same name. You should change the manifest to make sure the correct version is being picked up. – Ben Nov 20 '12 at 11:02
  • 1
    Depends is for native programs, not .net. There's not enough information here to help. You need to work out which module is not found. – David Heffernan Nov 20 '12 at 11:48
  • @DavidHeffernan: Depends will work on mixed assemblies and give correct information for the native part. Since there's a native C++ part here (apparently) using Depends is right. – MSalters Nov 20 '12 at 14:27
  • @MSalters Except that the native part, the pinvoke, is loaded at runtime, ultimately with `LoadLibrary`, so I don't think depends can say anything about it. – David Heffernan Nov 20 '12 at 14:32
  • @DavidHeffernan: Depends in fact can. – MSalters Nov 23 '12 at 08:15
  • @MSalters How does it manage that? – David Heffernan Nov 23 '12 at 08:27
  • @DavidHeffernan: I suspect it hooks `LoadLibrary` – MSalters Nov 23 '12 at 09:11
  • @MSalters Ahh. Sure it can do it at runtime. I meant a static analysis of the import table. – David Heffernan Nov 23 '12 at 09:13
  • Its all one solution in Visual Studio. The app is a C#.Net Winform that has a .Net reference to a Managed C++ dll. That dll in turn has dll dependency to a pure C++ dll. There are also a bunch of .Net projects and dll reference directly from the exe project. – meissnersd Nov 24 '12 at 15:47
  • When I run depends on the .Net exe it only list MSCoreee.dll and none of the other dependencies. So in this case it appears it would not have helped. Maybe reflector would have been worth trying. – meissnersd Nov 24 '12 at 15:49

1 Answers1

11

It is a simple "file not found" kind of error, but with the very awkward behavior that it doesn't tell you what DLL could not be found. Which might be the C++ DLL but also any implicit DLL dependencies it might have. Like the runtime support DLLs, very commonly missed, you can deploy them with the vcredist installer. Or deploying the Debug build of the DLL, that can't work.

Getting a decent diagnostic requires turning on loader snaps and a debugger. Invariably hard to do on a machine that doesn't have tools installed. The SysInternals' ProcMon utility is an excellent alternative, you'll see the program searching for the DLL. Albeit that you'll drown in the amount of trace data it generates. Work from the bottom of the trace backwards.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536