2015-09-03 101 views
1

請參閱以下更新。如何在主GUI窗口中顯示powershell作業的輸出?

看過多個網站和論壇後,我決定發佈一個問題,因爲我無法弄清楚這一點。

我有一個使用WinForms創建GUI窗口(如下所示)的PowerShell腳本。右側是在選定的複選框正在工作時顯示輸出。它起作用,除了窗口凍結和\或變成「沒有響應」。我一直在研究改變事情,讓他們在作業中運行,除非我找不出適當的語法來讓作業運行,並且還顯示它在列表框中的作用。我理解作業是單獨的PowerShell進程,但是當作業正在運行它正在執行的任務時,有沒有辦法顯示?

我不知道作什麼崗位的代碼段,因爲它種適用於整個事情,但這裏是它目前是怎樣的一個片段:

$handler_button1_Click= { 

    $domain=$TextBox2.Text 
    $user=$TextBox3.Text 
    $pass=$TextBox4.Text 
    $id=$TextBox1.Text 

    $listBox1.Items.Clear()  

    if ($checkBox1.Checked -and !$checkBox2.Checked) { uninstall } 

    if ($checkBox2.Checked -and $checkBox1.Checked) { $security -eq "y"; uninstall } 

    ... 

    if ($checkBox7.Checked) { $prog = "Firefox" 
           $appname = $firefox 
           $arguments = " -ms" 
           install } 
} 

現在我有複選框去使用不同的功能,或者使用ForEach循環卸載一堆軟件,或者安裝軟件。當我運行所選框時,我希望它顯示當前正在卸載或安裝的內容。它完成了它的工作,但是在完成所有工作之前,我看不到它在做什麼,然後列表刷新,並且所有內容都在那裏。

我試着讓函數變成一個變量,然後在上面的「checkbox.checked」代碼中用「Start-Job -ScriptBlock」調用它。我試過用不同的方法在Start-Job命令中包裝函數。我想我已經掌握了它,但我無法分辨,因爲它沒有顯示任何東西。

這需要在Windows 7

我已經把它貼在下面的GUI是什麼樣子的照片的工作。

任何幫助,將不勝感激。 謝謝。

更新:它

所以我得到了這份工作運行和顯示輸出的PS窗口。儘管如此,還沒有弄清楚如何使它在GUI的列表框中顯示輸出。

我遇到了將工作目錄設置爲腳本目錄的變量問題。它在主腳本中工作正常,但在將作業放入作業中時會拋出一個空或無效的錯誤。這裏是我用來測試這項工作的測試腳本......

理想情況下,我想要做的是讓腳本中的每個函數都是一個工作(除了主GUI功能)並且每個「上面的「checkbox.checked」部分開始一個作業,輸出顯示在GUI列表框中。

我從實際腳本複製\粘貼了大部分全局變量。有幾個「寫主機」行應該是「$ listbox1.items.add(」「)」。我將它們更改爲「寫入主機」,以便在測試時看到一些輸出。

有沒有辦法讓變量可用於其他工作?下面的代碼在我將變量列表放入$ updates內並手工輸入文件路徑到$ dir之前不起作用。

$updates = { 

$global:scriptpath = $MyInvocation.MyCommand.Path 
$global:dir = Split-Path $scriptpath 
$global:logfile = "$dir\Apps\log.txt" 
$global:ftppath = # REMOVED # 
$global:firefox = "install_firefox.exe" 
$global:chrome = "install_chrome.msi" 
$global:reader = "install_reader.exe" 
$global:java32 = "install_java_x32.exe" 
$global:java64 = "install_java_x64.exe" 
$global:flashie = "install_flash_ie.exe" 
$global:flashnonie = "install_flash_nonie.exe" 
$global:office = "install_o365.exe" 

function updates { 

$list = "Flash for IE","Flash for Other Browsers","Java 32-bit","Java 64-bit","Adobe Reader","Firefox","Chrome","Office 365" 

ForEach ($prog in $list) { 

    Try { 

     If ($prog -eq "Flash for IE") {$appname = $flashie} 
     If ($prog -eq "Flash for Other Browsers") {$appname = $flashnonie} 
     If ($prog -eq "Java 32-bit") {$appname = $java32} 
     If ($prog -eq "Java 64-bit") {$appname = $java64} 
     If ($prog -eq "Adobe Reader") {$appname = $reader} 
     If ($prog -eq "Firefox") {$appname = $firefox} 
     If ($prog -eq "Chrome") {$appname = $chrome} 
     If ($prog -eq "Office 365") {$appname = $office} 

     $filecheck = "$dir\Apps\$appname" 

     If(-not(Test-Path -path $filecheck)) { 

      write-host " Downloading $($prog) Installer..." 
      $File = "$dir\Apps\$appname" 
      $ftp = "$ftppath/$appname" 
      $webclient = New-Object System.Net.WebClient 
      $uri = New-Object System.Uri($ftp) 
      $webclient.DownloadFile($uri, $File) 

      " Downloaded $($prog)" >> $logfile 

     } # End If 

     Else { 

      $ftprequest = [System.Net.FtpWebRequest]::Create("$ftppath/$appname") 
      $ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::GetDateTimestamp 
      $response = $ftprequest.GetResponse().StatusDescription 
      $tokens = $response.Split(" ") 
      $code = $tokens[0] 

      $localtime = (Get-Item "$dir\Apps\$appname").LastWriteTimeUtc 

      If ($code -eq 213) { 

       $tokens = $tokens[1] 
       $localtime = "{0:yyyyMMddHHmmss}" -f [datetime]$localtime 

       If ($tokens -gt $localtime) { 

        write-host " Updating $($prog) Installer..." 
        $File = "$dir\Apps\$appname" 
        $ftp = "$ftppath/$appname" 
        $webclient = New-Object System.Net.WebClient 
        $uri = New-Object System.Uri($ftp) 
        $webclient.DownloadFile($uri, $File) 

        " Updated $($prog)" >> $logfile 

       } # End If 

       Else { $listBox1.Items.Add(" $($prog) skipped.") } 

      } # End If 

     } # End Else 

    } # End Try 

    Catch { write-host " ERROR: Couldn't update $($prog)" 
      " Error updating $($prog)" >> $logfile } 

} # End ForEach 

} # End Function 

} # End Variable 

Start-Job -Name "Updates" -ScriptBlock {updates} -InitializationScript $updates | Wait-Job | Receive-Job 

回答

0

可以每個作業單獨的一個任務,然後在檢查每個作業

If (($JobTask1).State -eq "Running")) 
    { 
    $Label1.Text = "JobTask1 is Still Running" 
    } 

另一種選擇是使用

Receive-Job $Jobs -Keep 

和操縱輸出的背景下使用的定時器找到已經完成的工作。

+0

感謝您的評論,但我不認爲這會做我想找的。現在,每個功能在運行時都會顯示文本。例如,當「卸載」功能正在運行時,它會爲其刪除的每個程序顯示「Uninstalling nameofprogram ...」。您的評論似乎只是確認整個工作是否正在運行。我想要一種方法來讓函數/作業生成的文本實時顯示在GUI中。我問得太多了嗎?這並不意味着諷刺,我真的很想知道。謝謝! – sloppyfrenzy

+0

當您執行Receive-Job時,它會顯示有關該過程的任何信息? – Avshalom

相關問題