检查系统中是否存在DLL

时间:2010-02-18 22:06:59

标签: c# windows winapi dll pinvoke

快速提问。我想知道我的应用程序正在执行的系统中是否存在DLL。

这在C#中是否可行? (以某种方式适用于所有Windows操作系统?)

对于DLL,我指的是非.NET经典dll(Win32 dll)

(基本上我想做一个检查,因为我使用的DLL可能存在或可能不存在于用户系统上,但我不希望应用程序在没有警告的情况下崩溃:P)

6 个答案:

答案 0 :(得分:15)

调用LoadLibrary API函数:

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

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

答案 1 :(得分:2)

我认为最好调用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。

答案 2 :(得分:1)

答案 3 :(得分:1)

我假设这是一个PInvoke电话?

如果是这样,最简单的方法是确定它是否存在是为了进行调用并捕获在文件不存在时导致的异常。

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

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

答案 4 :(得分:1)

实际上它不会抛出 FileNotFoundException

此外,对于 LoadLibrary

,需要在多个地方检查路径

.net中存在一个标准异常,它来自TypeLoadException,即 DllNotFoundException

最好的方法是在try..catch中包装方法/ PInvoke调用并处理DllNotFoundException,因为.net将检查应用程序路径以及作为PATH OS环境变量的一部分设置的任何其他路径。

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

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

答案 5 :(得分:1)

在.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
        }