通过Powershell远程会话执行时,程序输出不同

时间:2013-05-09 13:44:24

标签: c++ visual-c++ powershell powershell-remoting

我正在使用Visual Studio 2010开发Windows控制台应用程序,该应用程序在屏幕上打印进度百分比,以便使用当前数字覆盖最后一个数字。我正在使用回车来达到这个目的:

std::wcout
    << "[Running: "
    << std::setw(3)
    << std::setprecision(3)
    << percent
    << "%]"
    << '\r'
;

当我使用PSSesion在远程主机上通过PowerShell执行此程序时:

Enter-PSSession WWW.XXX.YYY.ZZZ -credential <UserName>
[WWW.XXX.YYY.ZZZ]: PS C:\> .\test.exe

与在PowerShell或cmd.exe中本地执行时相比,它的行为有所不同。我面临以下三个问题:

1)程序的控制台输出是不同的,因为它不会覆盖[Running xx%]在下一行中的打印,如下所示:

[Running  1%]
[Running  2%]
[Running  3%]
[Running  4%]
...

这类似于将程序输出重定向到文件时所发生的情况(单独carriage returnsnewlinescarriage returns + newlines组合替换)。< / p>

2)当程序向cout写入内容时,输出不会显示。它在执行结束时立即出现。 powershell是否缓存远程程序的输出并仅向调用者发送一次?如果两行之间存在显着的时间差(行表示两个newline之间的所有输出),则第一行被打印,好像它等待一段时间用于另一行newline,如果收到,则再次进入等待状态,如果在一定时间内没有收到(~500ms),它会将输出发送到呼叫者的最后newline(而不是所有累积的输出)。从我的代码中可以看出,没有newline导致最后一次打印所有[Running xx%]

3)在程序的某一点,我需要用户确认,但cin.fail()在远程执行中返回true。那么,有没有办法在这样的执行环境中获取用户输入?或者有没有办法通过Powershell检测程序是否正在远程执行(例如某些env变量)?

任何与此相关的帮助都将不胜感激。 :)

1 个答案:

答案 0 :(得分:1)

关于1),PowerShell Remoting的WinRM协议实际上只是命令及其序列化输出的输入/输出流。它没有终端仿真功能,因此当您远程运行时,它们的输出一次一行地反馈。如果您使用SSH或Telnet到powershell.exe的远程shell,您可能会看到您的期望。

对于2),默认输出缓冲模式似乎是“阻止”,因此这将解释您所看到的行为。您可以使用New-PSSessionOption cmdlet更改此设置,以便为New-PSSession创建的会话创建一个配置,该配置可以传递给远程感知cmdlet上的-Session参数。选项为OutputBufferingMode。如果将其设置为None,则应获得所需的行为。

# default output buffering mode is "none" for default options
$s = new-pssession localhost -sessionoption (new-pssessionoption)
enter-pssession $s

对于3),你应该能够以交互方式接受输入IIRC。看起来交互式的东西不能正常工作 - 我可能完全错误地记错了这一点。