使用JNA执行WMI时执行IWbemServices.ExecQuery时的问题

问题描述 投票:2回答:1

我正在尝试编写一个使用JNA执行WMI查询以在远程计算机上执行的Java程序(提供的用户名/密码)。

我正在尝试移植this WMI示例。我出于测试目的(直接提供的用户名/密码)修改了此代码here,并且工作正常。

但是,在我的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代码here

我也使用过oshi库。

任何与此有关的帮助都会有所帮助。谢谢

java com wmi jna wmi-service
1个回答
0
投票

最终解决方案可以找到here

© www.soinside.com 2019 - 2024. All rights reserved.