在Windows Java中检查USB驱动器的文件系统完整性



我们的应用程序涉及一个作为USB大容量存储设备安装的外部设备。我需要能够从运行在Windows上的Java应用程序中检查USB大容量存储设备的完整性。

目前我执行";chkdsk";,除非用户的计算机没有配置为英语,否则它可以正常工作。(因为我需要检查chkdsk输出来确定驱动器的状态。(而且,令人惊讶的是,并不是世界上每台计算机都配置了英语!

有一个Win32类称为";Win32_Volume;用一种称为";Chkdsk";这正是我想要的。

我需要从Java中调用它,而JNA似乎是可行的。

如何使用COM从Win32 WMI类调用方法?

您可以使用DeviceIoControl发送FSCTL_IS_VOLUME_DIRTY消息。

以下是调用DeviceIoControl的示例。

或者您可以使用WMI,Win32_Volume和Win32_LogicalDisk类都公开DirtyBitSet属性。然而,WMI确实集成了脚本语言,并且由于其令人难以置信的性能开销而不是首选。

您引用的带有Chkdsk方法的Win32_Volume文档表明它是传统的API,但尚未被弃用,因此您可以使用它。

当前的存储管理API等效于MSFT_Volume。它有一个Diagnose方法,看起来可以执行类似的功能。

要通过COM在WMI对象上执行方法,需要获得指向WbemServices对象的指针。它有一个ExecMethod方法,您可以调用它来执行WMI类所需的操作。检索该对象的代码在JNA的WbemcliUtil类中,作为connectServer((方法的返回类型。

您还需要类对象的完整路径;这可以通过查询WMI中的__PATH来获得,类似于查询任何其他字段的方式。相同的WbemcliUtil类有一个WmiQuery类,您可以实例化它来执行查询,从WmiResult中收集该路径。有关使用这些测试类的示例,请参阅JNA测试类。

最后,您可以执行WMI方法。下面的代码将为String属性实现它,例如,从MSFT_VolumeDiagnose方法中获得的MSFT_StorageDiagnoseResult对象。您必须区别对待其他返回类型。

/**
* Convenience method for executing WMI methods without any input parameters
* 
* @param svc
*            The WbemServices object
* @param clsObj
*            The full path to the class object to execute (result of WMI
*            "__PATH" query)
* @param method
*            The name of the method to execute
* @param properties
*            One or more properties returned as a result of the query
* @return An array of the properties returned from the method
*/
private static String[] execMethod(WbemServices svc, String clsObj, String method, String... properties) {
List<String> result = new ArrayList<>();
PointerByReference ppOutParams = new PointerByReference();
HRESULT hres = svc.ExecMethod(new BSTR(clsObj), new BSTR(method), new NativeLong(0L), null, null, ppOutParams,
null);
if (COMUtils.FAILED(hres)) {
return new String[0];
}
WbemClassObject obj = new WbemClassObject(ppOutParams.getValue());
VARIANT.ByReference vtProp = new VARIANT.ByReference();
for (String prop : properties) {
hres = obj.Get(new BSTR(prop), new NativeLong(0L), vtProp, null, null);
if (!COMUtils.FAILED(hres)) {
result.add(vtProp.getValue() == null ? "" : vtProp.stringValue());
}
}
obj.Release();
return result.toArray(new String[result.size()]);
}

查询COM对象的一个更完整的示例(我提取了上面的代码(在这个实用程序类中,它查询Win32_Process对象上的GetOwner()GetOwnerSid()方法。这是我向JNA贡献WbemCli类之前的遗留代码,所以您必须对其中的一些进行调整,但这应该是一个很好的起点。

相关内容

最新更新