2011-05-13 27 views
13

我想通過PowerShell顯示圖像。我做了script根據this forum post在PowerShell Form.Show()不能正常工作,但Form.ShowDialog()沒有

如果我使用ShowDialog()它可以正常工作,除非powershell執行在對話框啓動時停止。但是,這是通過模態對話框設計的。如果我在PowershellISE中調用Form.Show(),表格會顯示,但會凍結,無法移動或解散。如果我將代碼複製並傳遞到PowerShell控制檯,行爲類似。

如何使對話框非模態化,而不是凍結。

+3

展()可能不是一個好主意:http:// stackoverflow。com/questions/2192558/why-do-a-form-displayed-by-powershell-sometimes-not-show-up – keyboardP 2011-05-13 02:46:21

+0

這是一個很好的參考。 – 2011-05-13 10:58:40

回答

18

爲什麼它附加。

在Windows圖形程序中,創建窗口的線程必須在消息泵中循環,以便將來自用戶操作的消息重新分配(轉換)到Windows中的事件。

在模態窗口中,處理窗口顯示的模態代碼運行自己的消息泵循環,直到窗口關閉才返回。這就是爲什麼ShowDialog()之後的代碼在窗口關閉之前不會執行。

Show(),只是要求顯示窗口,但如果沒有泵循環來管理來自用戶操作的消息,它就會凍結。

二的簡單方法有兩個線程

該cmdlet啓動工作中使用另一個線程從Powershell的分配池,以便使該對話框非模態,而且不結冰。

function goForm 
{ 
    [void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms") 

    $file = (get-item 'C:\temp\jpb.png') 
    #$file = (get-item "c:\image.jpg") 

    $img = [System.Drawing.Image]::Fromfile($file); 

    # This tip from http://stackoverflow.com/questions/3358372/windows-forms-look-different-in-powershell-and-powershell-ise-why/3359274#3359274 
    [System.Windows.Forms.Application]::EnableVisualStyles(); 
    $form = new-object Windows.Forms.Form 
    $form.Text = "Image Viewer" 
    $form.Width = $img.Size.Width; 
    $form.Height = $img.Size.Height; 
    $pictureBox = new-object Windows.Forms.PictureBox 
    $pictureBox.Width = $img.Size.Width; 
    $pictureBox.Height = $img.Size.Height; 

    $pictureBox.Image = $img; 
    $form.controls.add($pictureBox) 
    $form.Add_Shown({ $form.Activate() }) 
    $form.ShowDialog() 
} 

Clear-Host 

start-job $function:goForm 

$name = Read-Host "What is you name" 
Write-Host "your name is $name" 
+0

如果他問這樣的問題,你真的認爲他給消息泵灌腸嗎? – x0n 2011-05-13 03:09:25

+5

好的,對你來說,知識就是一根香腸,最好讓人們無知......你是建築師...... – JPBlanc 2011-05-13 03:36:10

+5

x0n「那種問題」讓你覺得我不在乎香腸是怎麼樣的製作?是的,最後我確實需要GTD,所以在短期內我需要開始工作或者展示UI。然而,理解「爲什麼」可以幫助我評估這裏發生的事情。 – 2011-05-13 11:06:03

4

有一些方法可以使這項工作,但沒有什麼是值得花費五個小時在一個開放的論壇上解釋。還有其他免費的,縮小包裝的方式在PowerShell上做到這一點。最值得注意的是免費的WPF PowerShell工具包:Show-UI http://showui.codeplex.com/(以前稱爲WPK和/或PowerBoots - 現在已合併)

+7

5分鐘解釋像@JBBlanc一樣也值得;)爲什麼?這也是其他人一起來試圖弄清楚發生了什麼。除此之外,它可以進一步推動@Justin,因爲他可能很好奇所有關於消息抽取的內容。 +1 ... – stej 2011-05-13 04:59:02

2

如果您的目標實際上是在顯示圖像時不阻止交互式控制檯那麼您仍然可以使用該腳本,因爲它與ShowDialog相同,但您應該使用該腳本,例如Start-Job。因此,該對話框仍然是模態的,但會阻止另一個運行空間中的執行。主運行空間仍然可以用於調用其他命令。

注意事項:1)關閉交互式控制檯之前,應關閉所有打開的對話框。 2)如果你在意,你應該自己刪除完成的作業(當一個對話框關閉時,一個啓動它的作業仍然存在)。

我在我的自定義主機中使用了類似的方法,它工作正常。我還使用鏈接中的腳本對其進行了測試。我稍微改了一下,所以它被稱爲show-image.ps1並接受一個文件路徑作爲參數。

此命令顯示的圖像,並阻塞調用運行空間:

show-image.ps1 C:\TEMP\_110513_055058\test.png 

此命令顯示的圖像,並不會阻止調用運行空間:

Start-Job { show-image.ps1 $args[0] } -ArgumentList C:\TEMP\_110513_055058\test.png 
+0

根據你的評論,我只是意識到,停職或脫職似乎掛在這個功能之王的工作。你有沒有經歷過同樣的事情? – JPBlanc 2011-05-13 05:37:48

+0

只有當對話框關閉時,「Stop-Job」纔會結束。 「Remove-Job」在關閉對話框後正常工作,如果仍然打開對話框,則「無法刪除作業...因爲作業未完成」。 – 2011-05-13 05:49:21

+0

'Remove-Job -Force'可以工作,但它也會「等待」退出對話框。 – 2011-05-13 05:52:22

相關問題