Check if a DLL is present in the system

2019-01-15 13:54发布

问题:

quick question. I want to find out if a DLL is present in the system where my application is executing.

Is this possible in C#? (in a way that would work on ALL Windows OS?)

For DLL i mean a non-.NET classic dll (a Win32 dll)

(Basically I want to make a check cause I'm using a DLL that may or may not be present on the user system, but I don't want the app to crash without warning when this is not present :P)

回答1:

Call the LoadLibrary API function:

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

static bool CheckLibrary(string fileName) {
    return LoadLibrary(fileName) == IntPtr.Zero;
}


回答2:

I think it is better to call GetModuleHandle rather than LoadLibrary to check if a dll is loaded.

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

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

I would avoid calling LoadLibrary to check the presence of a dll. LoadLibrary will load the dll into the address space and load other modules as necessary. Assuming you don't need to actually use the dll, I'd stick with GetModuleHandle.



回答3:

Call LoadLibrary.

http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx



回答4:

I'm assuming this is a PInvoke call?

If so the easiest way to make this determine if it's present is to make the call and catch the exception that results if the file does not exist.

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

public static void SomeMethodWrapper() {
  try {
    SomeMethod();
  } catch (FileNotFoundException) {
    // Do Nothing 
  }
}


回答5:

Actually it does not throw FileNotFoundException.

Also for that one needs to check in multiple places for path, for the LoadLibrary

There is a standard exception in .net the is derived from TypeLoadException, that is DllNotFoundException.

Best way is to wrap a method/PInvoke call in try..catch and handle the DllNotFoundException since .net will check for application path as well as any other paths set as part of PATH OS Environment variable.

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

public static void SomeMethodWrapper() {
try {
      SomeMethod();
    } catch (DllNotFoundException) {
    // Handle your logic here
  }
}


回答6:

When using platform invoke calls in .NET, you could use Marshal.PrelinkAll(Type) method

Setup tasks provide early initialization and are performed automatically when the target method is invoked. First-time tasks include the following:

Verifying that the platform invoke metadata is correctly formatted.

Verifying that all the managed types are valid parameters of platform invoke functions.

Locating and loading the unmanaged DLL into the process.

Locating the entry point in the process.

As you can see, it performs additional checks other than if the dll exists, like locating the entry points (e.g if SomeMethod() and SomeMethod2() actually exist in the process like in the following code).

using System.Runtime.InteropServices;

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

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

Then use try...catch strategy to perform your check:

        try
        {
            // MY_PINVOKES class where P/Invokes are
            Marshal.PrelinkAll( typeof( MY_PINVOKES) );
        }
        catch
        {
            // Handle error, DLL or Method may not exist
        }