2013-02-23 197 views
1

我使用PowerShell v3.0启动新的cmd.exe进程,然后在其中加载Visual Studio命令提示符以执行生成,如下所示:如何使用PowerShell将命令提示符的输出转换为变量

Start-Process cmd.exe -ArgumentList $cmdArgumentsToRunMsBuildInVsCommandPrompt -WindowStyle $windowStyle -Wait 

这个工作,它会打开一个新的命令提示符窗口中,我可以看到生成发生,然后在构建完成的提示窗口关闭的命令。我希望能够获得写入命令提示符窗口的文本并将其存储在变量中,以检查构建是否通过。我尝试过使用它,但它不起作用; $ buildOutput变量为空:

Start-Process cmd.exe -ArgumentList $cmdArgumentsToRunMsBuildInVsCommandPrompt -WindowStyle $windowStyle -Wait -OutVariable buildOutput 
Write-Host "Build output = $buildOutput" 

这很有意义,因为cmd.exe进程没有返回任何文本;它只是将它写入它自己的窗口。有没有办法让我能够将该文本存储在原始PowerShell脚本使用的变量中?我知道我可以为MsBuild提供一个参数,让它将构建日志写入文件,但是我正在寻找一种不涉及写入日志文件并稍后删除它的解决方案。

任何建议表示赞赏。谢谢!

<#编辑#>

感谢所有迄今的答复!一个流行的建议是直接调用MsBuild.exe而不使用cmd.exe。我需要通过cmd.exe的原因是,如果直接从MsBuild.exe调用某些项目(例如XNA项目),则无法成功构建。相反,我需要从Visual Studio命令提示符中调用MsBuild.exe,以便(我假设)设置了所有必需的环境变量。我想我可以直接调用VS命令提示符,但它也会有和调用cmd.exe一样的问题。如果我找不到VS命令提示符,我会直接调用MsBuild.exe,所以这些答案仍然值得赞赏。

+1

为什么不用它写入日志?您可以使用PowerShell立即使用日志文件并将其删除。 – Matt 2013-02-23 00:16:46

+2

直接调用msbuild(或适当的可执行文件)并避免'cmd.exe'?我不确定'cmd.exe'“是否有”stdout。也许这受'/ c'标志影响? – 2013-02-23 00:22:33

+0

您可以将其作为后台作业运行(使用cmd/c),并使用接收作业控制输出的显示和最终处置。 – mjolinor 2013-02-23 01:59:28

回答

3

我已经解决了我的问题,使用来自我的问题的第一条评论的建议,即将构建输出写入日志文件,然后将其删除。这样,如果需要,我仍然可以向用户显示构建进度的cmd窗口,并在构建完成后检查构建输出。它还允许我在另一个进程中运行构建,所以如果我们不希望我们的脚本在继续执行之前等待构建完成,我们可以使用PassThru。

我创建了一个Invoke-MsBuild powershell模块,使用MsBuild进行构建的同时,还提供了大量的附加功能参数(如果构建成功或失败,可以显示/隐藏构建窗口,可以等待/不等待构建完成,可以自动显示构建失败的构建日志等)。你可以view and download the script from my blog

10

你可以随时捕捉控制台程序的输出是这样的:

$output = [string](nuget.exe) 

这里我用的NuGet($输出将包含可用的命令列表),当然你可以使用msbuild.exe与适当的参数。

+1

如果我想在当前进程上运行构建,这是一个很好的解决方案,但我希望在新进程上运行它以便它在自己的窗口中弹出,用户可以在需要时使用PassThru,以便在脚本继续执行之前不必等待构建完成。 Upvote虽然为有用的答案:) – deadlydog 2013-04-10 17:23:33

+0

这正是我一直在寻找。仅基于问题的标题,这就回答了100%的问题。可以理解的是,问题内容改变了需求。感谢您发布这个答案。 – 2016-11-22 20:30:08

2
$process = New-Object System.Diagnostics.Process; 
$process.StartInfo.UseShellExecute = $false; 
$process.StartInfo.RedirectStandardOutput = $true; 
$process.StartInfo.FileName = "cmd.exe"; 
$process.StartInfo.Arguments = $cmdArgumentsToRunMsBuildInVsCommandPrompt; 
$process.Start(); 
$outputStream = $process.StandardOutput; 
$outputStream.ReadToEnd(); 

您也可以重定向StandardError

+0

我确定这会起作用(我还没有测试它),但它也会阻止文本被写入cmd窗口。理想情况下,我仍然希望它写入cmd窗口,以便用户可以看到构建的进度,然后当构建完成时,我想检查该输出以查看构建是否失败。 Upvote虽然为有用的答案:) – deadlydog 2013-04-10 17:21:36

0

编辑:我结束了使用@大卫布拉班特的回答

我遇到了这个问题,并创造出了回波函数

function echo() 
{ 
    $input 
} 

这让我做到这一点

$output = &"cmd.exe" $args | echo