微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在简单示例中使用 WinRM C++ API

如何解决如何在简单示例中使用 WinRM C++ API

为什么我的代码无法使用 WinRM's C++ API 运行简单的可执行文件

//main.cpp
int main()
{
    ShellClient *shellClient = new ShellClient();
    
    //Set up the shell client here and connect to the localhost.
    //This seems to be working fine because I'm handling every
    //possible error code,and none of them are being triggered
    
    PCWSTR commandLine = L"\"MyExampleExecutable.exe\"";
    isOk = shellClient->runcommand(commandLine);
    
    if (!isOk)
        return 1;
        
    return 0;   
}

//ShellClient.cpp
bool ShellClient::runcommand(PCWSTR command)
{
    WSMAN_SHELL_ASYNC createCommandAsync;
    ZeroMemory(&createCommandAsync,sizeof(createCommandAsync));
    createCommandAsync.operationContext = this;
    createCommandAsync.completionFunction = (WSMAN_SHELL_COMPLETION_FUNCTION)CommandCreatedCallback;
    
    WSManRunShellCommand(shellHandle,command,NULL,&createCommandAsync,&commandHandle);
    
    if (commandHandle == NULL)//It is *always* NULL
    {
        std::cout << "command handle null" << std::endl;
        system("pause");
        return false;
    }
    
    return true;
}

一个可能的线索是我的 C++ 代码认为 shell 创建得很好,但是在我机器的事件查看器中,有这个:

WSMan operation CreateShell Failed,error code 2150859250

在撰写本文时,这个可爱的错误代码在输入 Google 时给出的结果恰好为零,因此很难知道它的含义。

我已经检查过的背景和常见解决方

正如同一作者在 here 中记录和解释的那样,大多数 WinRM 问题归结为连接或身份验证问题。就我而言,如果我故意输入不正确的用户凭据,则会收到身份验证错误,因此我知道我的程序正在连接并且在提供正确的用户名和密码时进行身份验证。还有:

  • 从命令行,我可以连接到我的本地机器并假装它是一个远程服务器,例如以下命令工作正常:
    winrs -r:http://localhost:5985 -u:COmpuTERNAME\Jeremy "dir"
  • winrm quickconfig 显示服务正在运行(我们已经知道,否则 winrs 命令将无法运行)
  • winrm get winrm/config 显示 TrustedHosts = localhostAllowUnencrypted = true,并且所有身份验证方法都设置为 true
  • this video 之后,我设置了注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy = 1
  • 在 Windows 10 中工作

先谢谢你!

解决方法

我不知道这一点,所以无法评论它是否是常识,但 Microsoft 有一个漂亮的 error lookup tool,您可以在其中输入错误代码(将其从正常数字转换为十六进制后),它告诉你这意味着什么。

在这种情况下,2150859250(十六进制中的803381F2)对应于:

  ERROR_WINRS_IDLETIMEOUT_OUTOFBOUNDS                            wsmerror.h
# The WS-Management service cannot process the request. The
# requested IdleTimeout is outside the allowed range.

在设置 WinRM shell 时,我执行了以下操作:

    WSMAN_SHELL_STARTUP_INFO  startupInfo;
    ZeroMemory(&startupInfo,sizeof(startupInfo));
    startupInfo.idleTimeoutMs = 1000;//not large enough!
    startupInfo.workingDirectory = L"C:\\";
    //other parameters of startupInfo set here

    WSManCreateShell(session,shellUri,&startupInfo,NULL,&createShellAsync,&shellHandle);

idleTimeoutMs 从 1000 更改为更大的数字(如 100000)解决了错误,我的程序现在可以正常工作了。

由于此参数的 official docs 表示 0 到 0xFFFFFFFF 之间的任何内容都是有效的,因此为什么值 1000 会引发此错误仍然是个谜。我把这个留给比我更有见识的人来回答,以防他们遇到这个问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。