如何检测DLL是否已安装/可用

时间:2013-01-28 16:59:57

标签: c# dllimport

检测DLL是否安装在C#中最有效的方法是什么? 我很擅长这个:msvcr80.dll。我试图从C#程序调用LoadLibrary互操作API调用,但它不起作用。我只需要检测它,而不是使用它。

2 个答案:

答案 0 :(得分:4)

Pinvoking msvcr80.dll很难。它是一个特殊的DLL,它存储在Windows并排缓存(c:\ windows \ winsxs)中,并且通常在机器上安装了许多版本。我在这台机器上有16个。并行缓存相当于非托管DLL的GAC。在代码中使用这样的DLL需要一个清单,说明要使用的msvcr80.dll的特定版本。

因此,您要做的第一件事就是将条目添加到您自己的程序清单中。 Project + Add New Item,选择Application Manifest项目模板。您必须编辑它以包含对msvcr80.dll的依赖。你的清单应该是这样的:

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
                <requestedExecutionLevel level="asInvoker" uiAccess="false" />
            </requestedPrivileges>
        </security>
    </trustInfo>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.6195" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
        </dependentAssembly>
    </dependency>
</asmv1:assembly>

请注意版本属性,8.0.50727.6195是最新的。其他常见的修订版本是42(原始RTM版本)和762(SP1版本)以及大量安全更新。您通常可以在清单中使用.42,更新部署的发布者策略文件将重定向到计算机上的最新安装版本。

另请注意processorArchitecture属性,如果要使用64位版本的DLL,则需要“amd64”。最好坚持使用x86并确保程序以32位模式运行。右键单击EXE项目,Properties,Build选项卡,Platform target = x86。

现在可以使用[DllImport]从DLL调用函数。像:

    [DllImport("msvcr80.dll", CallingConvention = CallingConvention.Cdecl)]
    private static extern IntPtr _errno();

我故意挑选了一个没有任何用处的无辜功能。因此,您可以将其设置为测试是否安装了具有所需版本号的DLL。抓住异常就知道它不在那里。如果你想在没有例外的情况下这样做,那么请调用LoadLibrary()。

我猜你不会指望这些并发症。一种完全不同的方法是使用Windows代码使用的等效DLL。只要你不试图消除“不寻常”的功能,那就没问题。每次安装Windows都有msvcrt.dll,无需检查它的存在,也不需要清单。只需更改[DllImport]属性中的DLL名称即可。但是请注意,当微软显着改变CRT的私人副本时,你会承担有关你的程序可能会破坏的风险。

答案 1 :(得分:1)

您需要检查PATH环境变量和全局程序集缓存下的目录,最好使用this API完成。