2015-09-03 64 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

相关问题