2013-02-23 194 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