1

I have a winforms .net4.5.2 application which depends on a c++\cli wrapper which is included in the VS project by reference. When the winforms application, that is built using Any CPU, is launched a assembly resolver is used to point out the correct platform dll for the reference and Assembly.Load(ed) in the platform specific folders in the root of the application folder i.e. \x64 or \x86.

This c++\cli is now built using the v140 platform toolset which depends on the Universal CRT dll:s. Looking here https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/ I was able to locate the necessary dll:s (41 * 2 of them) and I did what I was told to copy them inside the \x86 and \x64 folders. Now since the change to v140 platform my application does not start anymore and ProcessMonitor file operations tell me the following:

SUCCESS C:\MyApp\x64\TheCLIWrapper.x64.dll
SUCCESS C:\MyApp\x64\ADependency.dll
SUCCESS C:\MyApp\x64\msvcp140.dll
SUCCESS C:\MyApp\x64\vcruntime140.dll
SUCCESS C:\MyApp\x64\api-ms-win-crt-runtime-l1-1-0.dll
NAME NOT FOUND C:\MyApp\ucrtbase.dll

How is this even possible if before assembly resolving my c++\cli wrapper I explicitly set the dll directory (using SetDllDirectory) to the C:\MyApp\x64 folder? By this I mean why is the loading process looking in C:\MyApp for the ucrtbase.dll?

Naturally, if all the 41 dlls of a specific platform are copied to the root C:\MyApp\ folder it works but this is not an option for me, nor is the installation of c++ runtime executable on the clients running the application.

Does anyone have an idea or any tips on how to solve this deployment problem?

tompish
  • 79
  • 3
  • Since I anticipated that no one cares to answer a question about deployment in legacy products (probably because the only solution is to install the run-time which is not applicable in reality, in my perspective, in many different industries) I wrote the stupidest code I have ever written to solve this. Just before resolving the assembly a copy is made to the root folder of the currently running platform of all the 41 dll:s. This just makes me angry so sorry for ranting :/ but at-least I have a solution :) – tompish Mar 15 '16 at 10:42
  • Also suffering from this. I don't think I can accept such a solution though! :p – dten May 15 '16 at 11:28
  • oh think i got it :) – dten May 15 '16 at 11:36

2 Answers2

1

So you basically wanna do x-xopy deployment with x86-dll's in MyApp\x86, and x64-dll's in MyApp\x64?

How about explicitly loading the dll's with LoadLibrary?

Papademos
  • 21
  • 4
  • Four years later, what you suggested worked for me. I explicit loaded ucrtbase.dll in the program.cs after call setdlldirectory with my app's libraries relative path. – ClownCoder Feb 09 '20 at 19:39
0

I used procmon to inspect where the UCRT DLLs were trying to load each other from. Noticed the paths it was searching did not include the path set from the earlier SetDllDirectory. No matter what I tried the paths it searched seemed to only include the default values.

The working directory was always included as per Dynamic-Link Library Search Order and the only solution I could get was to change the current working directory to the appropriate one, load the DLL with the UCRT requirement, and change it back. Nothing else worked (including changing PATH environment variable)

Note this is very much not threadsafe

dten
  • 2,364
  • 21
  • 28