1

I have two application and install in different folders, let call it app A and B, A is main application and B is an COM module, A will start B through COM API after A started, there are some DLLs need to be loaded by B while B started, if I start A by double click the shortcut of A, every thing is ok, but if I install A, and start A by check the start A option in the last dialog of the installation, then B is started, but one of the DLLs load failed with error code 126 (ERROR_MOD_NOT_FOUND), if I exit and restart again by double click the shortcut, it works again.

Already do some googles and seems the only difference between start from shortcut and installation is current directory, ie, if start from installation option, same as start from the installer package folder with cmd, like open cmd, switch to the folder of installer package, then start app A with full path, I have try this, also works well.

My installer package is build by installshield.

Is anyone have some clues about this issue?

  1. Already try to switch current directory to the install path of A and B, both can not solve this issue.
  2. Already try to set dll directory to the install path of B, which also is the path of the failed DLL, not work too.
  3. Already try to load the DLL with full path, also failed.
    //SetCurrentDirectory(L"C:\Program Files (x86)\install path of A"); <<<not work
    //SetCurrentDirectory(L"C:\Program Files (x86)\install paht of B");   <<<not work
    //SetDllDirectory(L"C:\Program Files (x86)\DLL path");   <<<not work
    //m_hLibrary = LoadLibrary((LPCWSTR)DLL full path);   //not work
    m_hLibrary = LoadLibrary((LPCWSTR)dllName.c_str());   //failed with error code 126
Rick Zhang
  • 11
  • 2
  • 3
  • have you tried to escape the backslashes or using forward slashes? `L"C:\Program Files (x86)\DLL path"` to `L"C:\\Program Files (x86)\\DLL path"` – Zaiborg Mar 29 '19 at 09:55
  • If you have the source code, can't you just step through this in the source code? Set a breakpoint on the `LoadLibrary` line and then see what is up with the variable values? If not, are you familiar with the use of [ProcMon.exe](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon)? Set an include filter to include all your exe-file names, flush all events, then set to record, launch the exe and see what errors you see in the file event list? I can try to write this up if you are not familiar with it. [A rudimentary sample usage here](https://stackoverflow.com/a/47792474/129130). – Stein Åsmul Mar 29 '19 at 22:03
  • [Debugging executables with Visual Studio without the source code](https://learn.microsoft.com/en-us/visualstudio/debugger/how-to-debug-an-executable-not-part-of-a-visual-studio-solution?view=vs-2017). And the ancient tool [Dependency Walker](http://www.dependencywalker.com) has a Profiling feature that used to work, but rarely works these days (Profile menu once you open an exe). If nothing else ``Options`` => ``Configure Module Search Order...`` => ``Uncheck "Expand" and press "Default"`` => will give you the most normal module search order (varies in each version of Windows). – Stein Åsmul Mar 29 '19 at 22:12
  • Thanks all for your response, Just have some clue about this issue, it should be an depends issues, the failed DLL depends several DLLs and one of the DLL located in other folder, this folder have been added to environment path, but seems this folder not in dll search path while start from installation, if copy this dll to the install path, it works well. So now the problem is why the depends path not added to search path. will add more details soon. – Rick Zhang Apr 02 '19 at 09:49
  • Bumping @RickZhang to notify about Urman's answer. – Stein Åsmul Apr 05 '19 at 00:19

1 Answers1

0

It sounds like you have diagnosed the symptoms. Solving them may be tricky, as at least some versions of InstallShield call APIs that reduce the ability to load unexpected DLLs before an application folder is established. It appears that the effects of these calls carry over to your process when you launch it directly from the installer.

So first, oversimplified option 1: remove the option to start your app from the last page of the wizard. Poof, problem goes away. But this probably makes someone else unhappy.

Instead let's try to dive into what's going on. Depending on the exact version of InstallShield, it may be calling some combination of APIs, but the most likely culprit is a call to SetDllDirectory(L""); According to some quick research, this should only have an effect on implicitly loaded DLLs in child processes, but that doesn't appear to be the scenario you describe.

You've tried undoing this call by explicitly adding a directory; here are my recommended (but untested) options 2 and 3:

Michael Urman
  • 15,737
  • 2
  • 28
  • 44
  • Finally solve this problem by SetDllDirectory path of another dll which depends by the failed dll. Actually I have add the depends dll's path to system path, but seems the path not works if start from installer. – Rick Zhang Apr 10 '19 at 03:05
  • Oh, somehow I thought the question indicated it worked with an earlier version of InstallShield, so I focused on that difference. But yes, if you're altering PATH as part of the installation, you will also need to propagate that to anything launched directly from the installer. Sometimes we forget to check the obvious. Glad you got it! – Michael Urman Apr 10 '19 at 21:33