C# 当设备未插入时,如何确定设备驱动程序的版本?

C# 当设备未插入时,如何确定设备驱动程序的版本?,c#,wmi,wmi-query,C#,Wmi,Wmi Query,由于其他一些有用的StackOverflow问题,我找到了一种查询WMI设备驱动程序的方法。然而,在我看来,数据存储在不同的位置,这些位置不能很好地连接在一起 我有一个USB到串行端口电缆使用FTDI驱动程序。我可以查询Win32\u SystemDrivers以确定驱动程序是否已安装,如下所示: SelectQuery query = new SelectQuery("Win32_SystemDriver"); query.Condition = "Name = 'FTDIBUS'"; Ma

由于其他一些有用的StackOverflow问题,我找到了一种查询WMI设备驱动程序的方法。然而,在我看来,数据存储在不同的位置,这些位置不能很好地连接在一起

我有一个USB到串行端口电缆使用FTDI驱动程序。我可以查询
Win32\u 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);
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();
}
但那个集合并没有告诉我任何关于版本信息的事情。因此,我发现我可以查询
Win32\u PnPSignedDriver
来查找设备驱动程序的版本。所以我在做这样的事情:

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

ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection drivers = searcher.Get();
bool installed = (drivers.Count > 0);
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();
}
但是,只有当电缆(设备)实际插入时,第二个代码块才会成功。我想做的是检查已安装设备驱动程序的版本,不管设备当前是否已插入

如何执行此操作?

似乎可以为您提供相关驱动程序.sys文件的路径名

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

然后,您可以通过以下方式获取.sys文件版本:

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

请记住,你所要求的是解决鸡和蛋的问题,这对任何项目来说都不是一个非常健康的开始。即插即用Windows基于这样一种理念,即当设备可用时,可以动态定位设备驱动程序,并在必要时下载。那是一只鸡

如果驱动程序是预安装的或以前使用过的,那么您只能希望找到egg。并非完全罕见。在这种情况下,它将在驱动程序商店中提供。当你列举它时,你应该能够找到它

执行此操作的示例程序是。用C#写的,这是你想要的一个好的开始。我将复制屏幕截图:

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


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

这是正确的解决方案。非常感谢。然而,在今天早上的测试中,我发现了一个障碍:我似乎无法访问
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”(这是一个虚拟文件夹)。好吧,这似乎也在正确的轨道上,但我在这个问题的另一个答案上遇到了同样的问题。当我尝试使用
Process.Start()
调用pnputil.exe时,它说找不到该文件。再深入一点,我可以确认
File.Exists(@“C:\Windows\System32\PnPutil.exe”)
返回false。然而。。。文件肯定在那里!我可以在Windows资源管理器中看到它。如何让我的应用程序看到它并调用它?在64位操作系统上没有32位版本的pnputil.exe。这就是你想要跑的。Project+Properties,Compile选项卡,选择AnyCPU,并在看到“Preferred 32-bit”选项时取消选中它。或者,如果出于某种原因它必须是32位程序,则改为运行c:\windows\sysnative\pnputil.exe。