Проверьте, присутствует ли DLL в системе - PullRequest
8 голосов
/ 19 февраля 2010

быстрый вопрос. Я хочу выяснить, присутствует ли DLL в системе, где выполняется мое приложение.

Возможно ли это в C #? (таким образом, что будет работать на всех ОС Windows?)

Для DLL я имею в виду не-.NET классический dll (Win32 dll)

(В основном я хочу сделать проверку, потому что я использую DLL, которая может присутствовать или не присутствовать в пользовательской системе, но я не хочу, чтобы приложение аварийно завершало работу, если этого нет: P)

Ответы [ 6 ]

15 голосов
/ 19 февраля 2010

Вызовите функцию LoadLibrary API:

[DllImport("kernel32", SetLastError=true)]
static extern IntPtr LoadLibrary(string lpFileName);

static bool CheckLibrary(string fileName) {
    return LoadLibrary(fileName) == IntPtr.Zero;
}
2 голосов
/ 08 июня 2018

Я думаю, что лучше позвонить GetModuleHandle , а не LoadLibrary, чтобы проверить, загружена ли DLL.

[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);

public static bool IsDllLoaded(string path)
{
    return GetModuleHandle(path) != IntPtr.Zero;
}

Я бы не стал вызывать LoadLibrary для проверки наличия dll. LoadLibrary загрузит dll в адресное пространство и при необходимости загрузит другие модули. Предполагая, что вам на самом деле не нужно использовать dll, я бы использовал GetModuleHandle.

1 голос
/ 09 января 2019

При использовании вызовов платформ в .NET вы можете использовать Marshal.PrelinkAll(Type) метод

Задачи установки обеспечивают раннюю инициализацию и выполняются автоматически, когда вызывается целевой метод. Новые задания включают следующее:

Проверка правильности форматирования метаданных вызова платформы.

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

Нахождение и загрузка неуправляемой DLL в процесс.

Определение точки входа в процесс.

Как вы можете видеть, он выполняет дополнительные проверки, отличные от того, существует ли dll, например, находит точки входа (например, если SomeMethod() и SomeMethod2() действительно существуют в процессе, как в следующем коде).

using System.Runtime.InteropServices;

public class MY_PINVOKES
{
    [DllImport("some.dll")]
    private static void SomeMethod();

    [DllImport("some.dll")]
    private static void SomeMethod2();
}

Затем используйте стратегию try...catch для проверки:

        try
        {
            // MY_PINVOKES class where P/Invokes are
            Marshal.PrelinkAll( typeof( MY_PINVOKES) );
        }
        catch
        {
            // Handle error, DLL or Method may not exist
        }
1 голос
/ 09 июля 2013

На самом деле это не выдает FileNotFoundException .

Также для этого необходимо проверить путь в нескольких местах, для LoadLibrary

Существует стандартное исключение в .net, которое является производным от TypeLoadException, то есть DllNotFoundException .

Лучший способ - обернуть вызов метода / PInvoke в try..catch и обработать исключение DllNotFoundException, поскольку .net проверит путь приложения, а также любые другие пути, заданные как часть переменной среды PATH OS.

[DllImport("some.dll")]
private static void SomeMethod();

public static void SomeMethodWrapper() {
try {
      SomeMethod();
    } catch (DllNotFoundException) {
    // Handle your logic here
  }
}
1 голос
/ 19 февраля 2010

Я предполагаю, что это вызов PInvoke?

Если это так, самый простой способ сделать это, определить, присутствует ли он, - это сделать вызов и отловить исключение, которое возникает, если файл не существует.

[DllImport("some.dll")]
private static void SomeMethod();

public static void SomeMethodWrapper() {
  try {
    SomeMethod();
  } catch (FileNotFoundException) {
    // Do Nothing 
  }
}
1 голос
/ 19 февраля 2010
...