windows 检查系统中是否存在 DLL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2292578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:58:11  来源:igfitidea点击:

Check if a DLL is present in the system

c#windowswinapidllpinvoke

提问by feal87

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

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

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

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

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

对于 DLL,我的意思是非 .NET 经典 dll(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)

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

回答by SLaks

Call the LoadLibraryAPI function:

调用LoadLibraryAPI函数:

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

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

回答by Dr Yunke

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

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

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.

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

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

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

定位非托管 DLL 并将其加载到进程中。

定位流程中的入口点。

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).

正如你所看到的,它执行额外的检查比如果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();
}

Then use try...catchstrategy to perform your check:

然后使用try...catch策略执行检查:

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

回答by seshuk

Actually it does not throw FileNotFoundException.

实际上它不会抛出FileNotFoundException

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

也因为需要在多个地方检查路径,对于LoadLibrary

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

.net 中有一个标准异常,它是从 TypeLoadException 派生的,即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.

最好的方法是在 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
  }
}

回答by JaredPar

I'm assuming this is a PInvoke call?

我假设这是一个 PInvoke 调用?

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 (DllNotFoundException) {
    // Do Nothing 
  }
}