【问题标题】:How can I determine the version of a device driver when the device is not plugged in?未插入设备时,如何确定设备驱动程序的版本?
【发布时间】:2015-01-22 00:05:00
【问题描述】:

感谢其他一些有用的 StackOverflow 问题,我找到了一种在 WMI 中查询设备驱动程序的方法。但是,在我看来,数据存储在无法很好地连接在一起的不同地方。

我有一根使用 FTDI 驱动程序的 USB 转串口电缆。我可以查询Win32_SystemDrivers来确定驱动是否已经安装,如下所示:

SelectQuery query = new SelectQuery("Win32_SystemDriver");
query.Condition = "Name = 'FTDIBUS'";

ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection drivers = searcher.Get();
bool installed = (drivers.Count > 0);

但是那个集合并没有告诉我关于版本信息的任何事情。然后我发现我可以查询Win32_PnPSignedDriver 来查找设备驱动程序的版本。所以我正在做这样的事情:

SelectQuery query = new SelectQuery("Win32_PnPSignedDriver");
query.Condition = "DriverProviderName = 'FTDI'";

ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection drivers = searcher.Get();

foreach (ManagementBaseObject driverObject in drivers)
{
    ManagementObject driver = (ManagementObject)driverObject;
    string version = driver["DriverVersion"].ToString();
}

但是,只有在实际插入电缆(设备)时,第二个代码块才会成功。我想做的是检查已安装设备驱动程序的版本,无论设备是否是当前已插入。

我该怎么做?

【问题讨论】:

    标签: c# wmi wmi-query


    【解决方案1】:

    看来Win32_SystemDriver class 可以为您提供相关驱动程序.sys 文件的路径名。

    示例:“\SystemRoot\System32\drivers\afd.sys”

    然后你可以得到 .sys 文件版本:

    String path = @"C:\Windows\System32\drivers\afd.sys"
    var myFileVersionInfo = FileVersionInfo.GetVersionInfo(path);
    var version = myFileVersionInfo.ProductVersion;
    

    【讨论】:

    • 这是正确的解决方案。谢谢!然而,在我今天早上的测试中,我发现了一个障碍:我似乎无法访问C:\Windows\System32\drivers 文件夹中的任何文件。我手动将 driver.sys 文件复制到另一个文件夹中,然后运行GetVersionInfo() 命令来验证它是否有效(确实有效)。但即使我可以在 Windows 资源管理器中看到该文件,但当我在 C# 中调用 File.Exists() 时,它会返回 false。我还尝试将 app.manifest 更改为以管理员身份运行,但这也没有奏效。如何访问这些驱动程序文件?
    • 我认为您必须以管理员身份运行程序才能访问 windows 文件夹。要在 VisualStudio 中进行测试,您必须以管理员身份运行 VisualStudio 本身(右键单击 VS 图标,然后以管理员身份运行)
    • 如前所述(关于 app.manifest 的评论),我已经尝试过了,但不幸的是这并没有成功。
    • 我知道在 x64 系统上使用 32 位应用程序访问 System32 存在问题。你可以试试 x64 吗?
    • 另一位评论者引导我找到解决方案......我只需将路径中的“System32”替换为“Sysnative”(这是一个虚拟文件夹)。成功了。
    【解决方案2】:

    请记住,您要求解决先有鸡还是先有蛋的问题,这对任何程序来说都不是一个非常健康的开始。 Windows 中的即插即用建立在设备可用时可以动态定位设备驱动程序的概念,并在必要时下载它。那是一只鸡。

    如果驱动程序已预先安装或以前使用过,您只能希望找到鸡蛋。并非完全不常见。在这种情况下,它将在 驱动程序商店 中可用。枚举的时候应该能找回来。

    执行此操作的示例程序是available here。用 C# 编写,因此是您想要的一个好的开始。我将截图复制:

    请注意显示的驱动程序日期和版本,以及您要询问的内容。请记住,可能存在多个版本。您可能想看看源代码,它非常简单。它实际上依赖于 Windows 实用程序来填充 ListView,使用 /e 选项的 PnPUtil.exe 会枚举存储。尝试从命令行运行它。

    您还可以使用资源管理器轻松查看存储内容,文件存储在 c:\windows\system32\driverstore\filerepository 中。阅读 .inf 文件以添加额外的过滤可能很有用。您得到的 .inf 文件名,列在屏幕截图的第一列中,实际上是复制到 c:\windows\inf 目录中的文件名。

    【讨论】:

    • 好的,这似乎也是在正确的轨道上,但我在这个问题的另一个答案中遇到了同样的问题。当我尝试使用Process.Start() 调用 pnputil.exe 时,它​​说找不到该文件。再深入一点,我可以确认File.Exists(@"C:\Windows\System32\PnPutil.exe") 正在返回错误。但是......文件肯定在那里!我可以在 Windows 资源管理器中看到它。如何让我的应用程序看到并调用它?
    • 在 64 位操作系统上没有 32 位版本的 pnputil.exe。这就是您要运行的内容。 Project + Properties,Compile选项卡,选择AnyCPU并在看到它时取消选中“Prefer 32-bit”选项。或者如果由于某种原因它必须是 32 位程序,则运行 c:\windows\sysnative\pnputil.exe。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多