代码之家  ›  专栏  ›  技术社区  ›  feal87

检查系统中是否存在DLL

  •  8
  • feal87  · 技术社区  · 15 年前

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

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

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

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

    6 回复  |  直到 6 年前
        1
  •  15
  •   SLaks    15 年前

    呼叫 LoadLibrary API函数:

    [DllImport("kernel32", SetLastError=true)]
    static extern IntPtr LoadLibrary(string lpFileName);
    
    static bool CheckLibrary(string fileName) {
        return LoadLibrary(fileName) == IntPtr.Zero;
    }
    
        2
  •  2
  •   Justin Kotalik    7 年前

    我想打电话比较好 GetModuleHandle 而不是加载库来检查是否加载了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。

        3
  •  1
  •   Steven Sudit    15 年前
        4
  •  1
  •   JaredPar    15 年前

    我假设这是一个PInvoke电话?

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

    [DllImport("some.dll")]
    private static void SomeMethod();
    
    public static void SomeMethodWrapper() {
      try {
        SomeMethod();
      } catch (FileNotFoundException) {
        // Do Nothing 
      }
    }
    
        5
  •  1
  •   seshuk    12 年前

    实际上它不会扔 文件未找到异常 .

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

    .NET中有一个标准异常,它是从typeloadException派生的,即 dllnotfoundException(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
      }
    }
    
        6
  •  0
  •   Ricardo González    6 年前

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