C# 检查系统中是否存在DLL

C# 检查系统中是否存在DLL,c#,windows,winapi,dll,pinvoke,C#,Windows,Winapi,Dll,Pinvoke,快速提问。我想知道应用程序执行的系统中是否存在DLL 这在C#中可能吗?(以一种在所有Windows操作系统上都能工作的方式?) 对于DLL,我指的是非.NET经典DLL(Win32 DLL) (基本上我想做一个检查,因为我使用的DLL可能在用户系统上存在,也可能不存在,但我不希望应用程序在没有警告的情况下崩溃:p)调用LoadLibrary 我想这是一个PInvoke电话 如果是这样的话,确定它是否存在的最简单方法是调用并捕获文件不存在时产生的异常 [DllImport("some.dll")

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

这在C#中可能吗?(以一种在所有Windows操作系统上都能工作的方式?)

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

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

调用LoadLibrary


我想这是一个PInvoke电话

如果是这样的话,确定它是否存在的最简单方法是调用并捕获文件不存在时产生的异常

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

public static void SomeMethodWrapper() {
  try {
    SomeMethod();
  } catch (DllNotFoundException) {
    // Do Nothing 
  }
}
调用API函数:

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

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

实际上,它不会抛出FileNotFoundException

此外,还需要在多个位置检查加载库的路径

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

在.NET中使用平台调用时,可以使用
Marshal.PrelinkAll(Type)
方法

安装任务提供早期初始化,并可执行 在调用目标方法时自动执行。首次任务 包括以下内容:

验证平台调用元数据的格式是否正确

验证所有托管类型是否都是平台的有效参数 调用函数

查找非托管DLL并将其加载到进程中

在流程中定位入口点

如您所见,除了dll是否存在之外,它还执行其他检查,例如定位入口点(例如,如果
SomeMethod()
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
        }

这不是一个简单的单一呼叫,第一个呼叫可能并不总是相同的。我需要一个更高层次的检查来详细说明这个主题?目标是在文件不存在时不出现错误,或者找到存在的内容。目标是知道dll是否不存在,并向用户显示“您缺少dll xxx.dll。去更新您的系统”。这不仅仅是检查库,它会加载并保持加载。你必须手动加载FreeLibrary。无论如何,我的应用程序都会加载该库(因为它100%被应用程序使用:D),因此我认为FreeLibrary是不必要的。IMHO the FreeLibrary是必需的-否则你会泄漏对该库的引用。现在这可能无关紧要,但将来,有人会认为CheckLibrary没有副作用,它会烧死你。Larry是对的,更不用说它会给你的应用程序验证程序检查带来噪音。您正在使用AppVerifier检查bug,对吗??右??“系统在所有加载的模块上维护每个进程的引用计数。调用LoadLibrary会增加引用计数。调用FreeLibrary或FreeLibraryAndExitThread函数会减少引用计数。当模块的引用计数达到零或进程终止时,系统会卸载模块(不考虑引用数量)。“引用MSDN,但无论如何免费图书馆不需要花费任何费用。我要补充一点:p这应该是选择的答案。
        try
        {
            // MY_PINVOKES class where P/Invokes are
            Marshal.PrelinkAll( typeof( MY_PINVOKES) );
        }
        catch
        {
            // Handle error, DLL or Method may not exist
        }