Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specify the search path for DllImport in .NET

Tags:

.net

dllimport

Is there a way to specify the paths to be searched for a given assembly that is imported with DllImport?

[DllImport("MyDll.dll")]
static extern void Func();

This will search for the dll in the app dir and in the PATH environment variable. But at times the dll will be placed elsewhere. Can this information be specified in app.config or manifest file to avoid dynamic loading and dynamic invocation?

like image 914
Stefan Avatar asked May 19 '10 10:05

Stefan


People also ask

What is a DLL search path?

Specifies the paths that are used to search for DLLs that provide functions for platform invokes. This enumeration has a FlagsAttribute attribute that allows a bitwise combination of its member values. Include the application directory in the DLL search path.

How to find the relative path of a DLL file?

[DllImport ("MyAppDll.dll")] // relative path; just give the DLL's name static extern bool MyGreatFunction (int myFirstParam, int mySecondParam); But if that doesn't work for whatever reason, and you need to force the application to look in a different directory for the DLL, you can modify the default search path using the SetDllDirectory function.

Is there a way to limit DllImport search paths?

The DllImport search paths can be additionally limited using DefaultDllImportSearchPath. Even better than Ran's suggestion of using GetProcAddress, simply make the call to LoadLibrary before any calls to the DllImport functions (with only a filename without a path) and they'll use the loaded module automatically.

How do I search for the dependencies of a DLL?

Search for the dependencies of a DLL in the folder where the DLL is located before searching other folders. Include any path that was explicitly added to the process-wide search path by using the Win32 AddDllDirectory function.


3 Answers

Call SetDllDirectory with your additional DLL paths before you call into the imported function for the first time.

P/Invoke signature:

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

To set more than one additional DLL search path, modify the PATH environment variable, e.g.:

static void AddEnvironmentPaths(string[] paths)
{
    string path = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
    path += ";" + string.Join(";", paths);

    Environment.SetEnvironmentVariable("PATH", path);
}

There's more info about the DLL search order here on MSDN.


Updated 2013/07/30:

Updated version of the above using Path.PathSeparator:

static void AddEnvironmentPaths(IEnumerable<string> paths)
{
    var path = new[] { Environment.GetEnvironmentVariable("PATH") ?? string.Empty };

    string newPath = string.Join(Path.PathSeparator.ToString(), path.Concat(paths));

    Environment.SetEnvironmentVariable("PATH", newPath);
}
like image 160
Chris Schmich Avatar answered Nov 11 '22 18:11

Chris Schmich


Try calling AddDllDirectory with your additional DLL paths before you call into the imported function for the first time.

If your Windows version is lower than 8 you will need to install this patch, which extends the API with the missing AddDllDirectory function for Windows 7, 2008 R2, 2008 and Vista (there is no patch for XP, though).

like image 32
jvrdev Avatar answered Nov 11 '22 18:11

jvrdev


This might be useful DefaultDllImportSearchPathsAttribute Class
E.g.

[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)]

Also note you can use AddDllDirectory as well so you aren't screwing up anything already there:

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AddDllDirectory(string path);
like image 45
Eric Avatar answered Nov 11 '22 18:11

Eric