我正在尝试编写一个 Java 程序,它使用 JNA 执行 WMI 查询以在远程机器上执行(提供的用户名/密码)。
我正在尝试移植这个WMI 示例。我出于测试目的在此处修改了此代码(直接提供的用户名/密码),它工作正常。
但是,在我的 java 代码中,当使用ExecQuery执行查询时,我收到错误代码0x80070005。
String machineName = "machine";
String userNameWithDomain = "\\administrator";
String pass = "Password";
String namespace = "\\\\" + machineName + "\\ROOT\\CIMV2";
BSTR username = OleAuto.INSTANCE.SysAllocString(userNameWithDomain);
BSTR password = OleAuto.INSTANCE.SysAllocString(pass);
BSTR WQL = OleAuto.INSTANCE.SysAllocString("WQL");
HRESULT hres = null;
hres = Ole32.INSTANCE.CoInitializeEx(null, Ole32.COINIT_MULTITHREADED);
switch (hres.intValue()) {
case COMUtils.S_OK:
case COMUtils.S_FALSE:
case WinError.RPC_E_CHANGED_MODE:
break;
default:
throw new Wbemcli.WbemcliException("Failed to initialize COM library.", hres.intValue());
}
hres = Ole32.INSTANCE.CoInitializeSecurity(null, -1, null, null, Ole32.RPC_C_AUTHN_LEVEL_DEFAULT, Ole32.RPC_C_IMP_LEVEL_IMPERSONATE, null, Ole32.EOAC_NONE, null);
if (COMUtils.FAILED(hres) && hres.intValue() != WinError.RPC_E_TOO_LATE) {
Ole32.INSTANCE.CoUninitialize();
throw new Wbemcli.WbemcliException("Failed to initialize security.", hres.intValue());
}
PointerByReference pSvc = new PointerByReference();
IWbemLocator loc = IWbemLocator.create();
BSTR namespaceStr = OleAuto.INSTANCE.SysAllocString(namespace);
hres = loc.ConnectServer(namespaceStr, username, password, null, 0, null, null, pSvc);
OleAuto.INSTANCE.SysFreeString(namespaceStr);
loc.Release();
if (COMUtils.FAILED(hres)) {
throw new Wbemcli.WbemcliException(String.format("Could not connect to namespace %s.", namespace), hres.intValue());
}
String user = userNameWithDomain.substring(userNameWithDomain.indexOf("\\") + 1);
String domainName = userNameWithDomain.substring(0, userNameWithDomain.indexOf("\\"));
COAUTHIDENTITY auth = COAUTHIDENTITY.newAuth(user, domainName, pass);
Pointer pAuth = new Pointer(-1);
Pointer.nativeValue(pAuth, -1);
LPOLESTR COLE_DEFAULT_PRINCIPAL = new LPOLESTR(pAuth);
hres = Ole32.INSTANCE.CoSetProxyBlanket(pSvc.getValue(), Ole32.RPC_C_AUTHN_DEFAULT, Ole32.RPC_C_AUTHZ_DEFAULT, COLE_DEFAULT_PRINCIPAL, Ole32.RPC_C_AUTHN_LEVEL_PKT_PRIVACY, Ole32.RPC_C_IMP_LEVEL_IMPERSONATE, auth, Ole32.EOAC_NONE);
if (COMUtils.FAILED(hres)) {
new IWbemServices(pSvc.getValue()).Release();
throw new Wbemcli.WbemcliException("Could not set proxy blanket.", hres.intValue());
}
IWbemServices svc = new IWbemServices(pSvc.getValue());
String query = "SELECT BuildNumber,Caption,OSArchitecture,Version FROM Win32_OperatingSystem";
PointerByReference pEnumerator = new PointerByReference();
BSTR queryStr = OleAuto.INSTANCE.SysAllocString(query);
hres = svc.ExecQuery(WQL, queryStr, Wbemcli.WBEM_FLAG_FORWARD_ONLY | Wbemcli.WBEM_FLAG_RETURN_IMMEDIATELY, null, pEnumerator);
OleAuto.INSTANCE.SysFreeString(queryStr);
if (COMUtils.FAILED(hres)) {
svc.Release();
throw new Wbemcli.WbemcliException(String.format("Query '%s' failed.", query), hres.intValue());
}
IEnumWbemClassObject obj = new IEnumWbemClassObject(pEnumerator.getValue());
System.out.println("Done");
在线发生错误
hres = svc.ExecQuery(WQL, queryStr, Wbemcli.WBEM_FLAG_FORWARD_ONLY | Wbemcli.WBEM_FLAG_RETURN_IMMEDIATELY, null, pEnumerator);
对于提供的凭据,我的 C++ 代码版本运行良好。另外,我可以使用 powershell & WMIC 来检索数据。我在这里附上了整个java代码
我也使用过oshi库。
任何有关这方面的帮助都会有所帮助。谢谢