Укажите путь поиска для DllImport в .NET - PullRequest
52 голосов
/ 19 мая 2010

Есть ли способ указать пути для поиска для данной сборки, которая импортируется с помощью DllImport?

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

Это будет искать DLL в директории приложения и в переменной окружения PATH. Но иногда dll будет размещен в другом месте. Можно ли указать эту информацию в файле app.config или манифесте, чтобы избежать динамической загрузки и динамического вызова?

Ответы [ 3 ]

66 голосов
/ 19 мая 2010

Вызовите SetDllDirectory, указав дополнительные пути к DLL, прежде чем вызывать импортированную функцию в первый раз.

P / Invoke подпись:

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

Чтобы задать более одного дополнительного пути поиска DLL, измените переменную среды PATH, например ::

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

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

Более подробная информация о порядке поиска DLL здесь, в MSDN .


Обновлено 2013/07/30:

Обновленная версия вышеперечисленного с использованием 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);
}
14 голосов
/ 29 мая 2012

Попробуйте вызвать AddDllDirectory с дополнительными путями к DLL, прежде чем вызывать импортированную функцию в первый раз.

Если ваша версия Windows ниже 8, вам нужно установить этот патч , который расширяет API с отсутствующей функцией AddDllDirectory для Windows 7, 2008 R2, 2008 и Vista (нет хотя патч для XP).

1 голос
/ 29 июля 2017

Это может быть полезно DefaultDllImportSearchPathsAttribute Class
Например

[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)]

Также обратите внимание, что вы также можете использовать AddDllDirectory , чтобы вы ничего не напортачилиуже есть:

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