2010-05-19 5 views
50

Czy istnieje sposób określenia ścieżek do przeszukiwania dla danego zestawu, który jest importowany za pomocą DllImport?Określ ścieżkę wyszukiwania dla DllImport w .NET

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

Spowoduje to wyszukanie biblioteki dll w katalogu aplikacji i zmiennej środowiskowej PATH. Ale czasami biblioteka dll zostanie umieszczona w innym miejscu. Czy te informacje można określić w pliku app.config lub manifest, aby uniknąć dynamicznego ładowania i wywoływania dynamicznego?

Odpowiedz

65

Zadzwoń pod SetDllDirectory z dodatkowymi ścieżkami DLL, zanim po raz pierwszy uruchomisz importowaną funkcję.

P/Invoke podpis:

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

Aby ustawić więcej niż jedną dodatkową ścieżkę przeszukiwania DLL, modyfikować zmienną PATH środowiska, np

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

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

tam więcej informacji o DLL Porządek wyszukiwania here on MSDN.


Updated 2013/07/30:

zaktualizowana wersja powyżej używając 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); 
} 
+0

Dzięki, działa świetnie po wywołaniu SetDllDirectory od konstruktora statycznego. – Stefan

+0

AFAIK, niestety nie rozwiązuje problemu wielu dodatkowych katalogów wyszukiwania. – Stefan

+0

@Stefan, zobacz moją poprawioną odpowiedź na dodanie wielu katalogów. –

14

Spróbuj zadzwonić AddDllDirectory ze swoimi dodatkowymi ścieżkami DLL zanim zadzwonisz do funkcji importowanej po raz pierwszy.

Jeśli twoja wersja Windows jest mniejsza niż 8, musisz zainstalować this patch, która rozszerza API o brakującą funkcję AddDllDirectory dla Windows 7, 2008 R2, 2008 i Vista (nie ma jednak łatki dla XP).

+1

Brzmi jak dobry pomysł, ale jak powinien wyglądać DllImport? –

0

To może być przydatne DefaultDllImportSearchPathsAttribute Class
E.g.

[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)] 

pamiętać Również można użyć AddDllDirectory, jak również tak, że nie są przekręcane nic już tam:

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