Temporarily adding a directory to the Windows 7 DLL search path

I want to temporarily add a directory to the DLL search path - is there a proper way to do this in Windows 7?

Scenario

I have a C # application, let it WonderApp.

WonderApp needs to call the C ++ DLL located in C:\MyPath . So, as part of the WonderApp Program.Main() , I added the following command:

 Environment.SetEnvironmentVariable("PATH", "C:\\MyPath;" + Environment.GetEnvironmentVariable("PATH")); 

According to this article , adding a directory to PATH should also add it to the directory search for DLLs.

The solution works fine in Windows XP: if I add the directory to PATH , the DLL will load and the program will work fine. If I do not add the directory, the DLL does not load, with a "not found" error.

However, this does not work for Windows 7.

So, I decided, let him try using SetDllDirectory() . Like this:

 [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)] private static extern bool SetDllDirectory(string lpPathName); 

And, later:

  bool success = SetDllDirectory(Util.Paths.GetApplicationDataDir()); 

success is true , but the dll is still not loading.

Finally, if I set PATH to enable C:\MyPath manually, before running the application - it all works! The DLL loads and works very well.

So for re-iteration:

Is there a correct way to temporarily add a directory to a DLL search path in Windows 7?

UPDATE:. Using Process Explorer, I checked the application runtime, and "C: \ MyPath" really was in PATH ! In addition, I saw that Helper.dll was on the list of open descriptors (as a DLL, not just a file), and it still claimed to not find it.

+7
c # windows-7 dllimport
source share
3 answers

My solution is simple, but it’s ridiculous for me to resort to it.

I wrote another Shell build that changes the environment, starts WonderApp, and shuts down.

By changing the PATH before starting the main application (WonderApp), the main path to finding the DLL application includes directories added to the modified PATH .

It looks like this:

 namespace shell { static class program { [dllimport("kernel32.dll", charset = charset.auto, setlasterror = true)] public static extern bool setenvironmentvariable(string lpname, string lpvalue); private static string joinargstosinglestring(string[] args) { string s = string.empty; for (int i = 0; i < args.length; ++i) { if (!string.isnullorempty(s)) { s += " "; } s += "\"" + args[i] + "\""; } return s; } [stathread] static void main(string[] args) { string pathbefore = environment.getenvironmentvariable("path"); string wewant = util.paths.getapplicationdatadir() + ";" + pathbefore; setenvironmentvariable("path", wewant); Process process = Process.Start(".\\WonderApp.exe", joinArgsToSingleString(args)); } } } 

I would like to find the best solution!

0
source share

You can add custom DLL loading logic to a C # application using the AssemblyResolve event.

This page contains a good summary with code examples: http://support.microsoft.com/kb/837908

Just like you, I found that changing the PATH environment variable for a running C # application does not affect the behavior of the DLL search. Perhaps AppDomain caches the PATH value at startup? You can use the AssemblyResolve event to get around this.

See also How to add a folder to the assembly search path at run time in .NET?

+2
source share

I think this is due to resolution issues.

Try turning off UAC and running the code again. Check if the path update is working.

If that were the case, at least you know where to start ...

+1
source share

All Articles