简体   繁体   English

Powershell关闭弹出框

[英]Powershell closing popup box

I'm trying to create a popup window that stays open until the script finishes. 我正在尝试创建一个保持打开的弹出窗口,直到脚本完成。

I have the following code to create a popup box 我有以下代码来创建一个弹出框

$wshell = New-Object -ComObject Wscript.Shell

$wshell.Popup("Operation Completed",0,"Done",0x1)

$wshell.quit

I figured $wshell.quit would close the window, but it doesn't. 我想$ wshell.quit会关闭窗口,但事实并非如此。 Is there a way to close this dialog box from within the script without user interaction? 有没有办法在没有用户交互的情况下从脚本中关闭此对话框?

You can, from within power shell, open internet explorer, displaying a local html page (aka a splash screen) then, when done, close it 您可以从电源shell中打开Internet Explorer,显示本地html页面(又名启动画面),然后在完成后关闭它

$IE=new-object -com internetexplorer.application
$IE.navigate2("www.microsoft.com")
$IE.visible=$true
 ...
$IE.Quit()

Some reading Here https://social.technet.microsoft.com/Forums/ie/en-US/e54555bd-00bb-4ef9-9cb0-177644ba19e2/how-to-open-url-through-powershell?forum=winserverpowershell 一些阅读这里https://social.technet.microsoft.com/Forums/ie/en-US/e54555bd-00bb-4ef9-9cb0-177644ba19e2/how-to-open-url-through-powershell?forum=winserverpowershell

Some more reading Here How to properly close Internet Explorer when launched from PowerShell? 还有一些阅读在这里如何从PowerShell启动时正确关闭Internet Explorer?

See https://msdn.microsoft.com/en-us/library/x83z1d9f(v=vs.84).aspx for the parameters. 有关参数,请参阅https://msdn.microsoft.com/en-us/library/x83z1d9f(v=vs.84).aspx The one you need is [nSecondsToWait], if the value is 0 the script waits indeffinetly, use a value for the seconds and it wil close by itself. 你需要的是[nSecondsToWait],如果值为0,则脚本不等待,使用秒的值,它将自行关闭。

intButton = wShell.Popup(strText,[nSecondsToWait],[strTitle],[nType]) intButton = wShell.Popup(strText,[nSecondsToWait],[strTitle],[nType])

Another way would be sending a keystoke to the dialog with wshShell.SendKeys "%N" 另一种方法是使用wshShell.SendKeys "%N"向对话框发送一个wshShell.SendKeys "%N"

Using the first method here an example of what you could do. 在这里使用第一种方法,你可以做的一个例子。 I'm using vbscript here, no experience with powershell but it's almost the same solution. 我在这里使用vbscript,没有使用PowerShell的经验,但它几乎是相同的解决方案。

Set wShell = WScript.CreateObject("WScript.Shell")
count  = 1
result = -1
Do while result = -1
  result = wShell.Popup("Operation Completed", 1, "Done", 0)
  count = count + 1
  Wscript.echo count
  if count = 10 then Exit Do ' or whatever condition
Loop

The use of $wsheel.quit won't work here because in PowerShell when you execute $wshell.Popup(..) the session will wait untill the form is closed. $wsheel.quit的使用在这里不起作用,因为在PowerShell中执行$wshell.Popup(..) ,会话将等待,直到表单关闭。
You won't be able to run any other command untill the window will be closed. 您将无法运行任何其他命令,直到窗口将被关闭。

What you can do is to create the popup window in different session and by that you can run you code and when your code finish, search for the job and kill it. 你可以做的是在不同的会话中创建弹出窗口,你可以运行代码,当你的代码完成后,搜索工作并杀死它。

Solution #1: 解决方案#1:

function killJobAndItChilds($jobPid){
    $childs = Get-WmiObject win32_process | where {$_.ParentProcessId -eq $jobPid}
    foreach($child in $childs){
        kill $child.ProcessId
    }
}

function Kill-PopUp($parentPid){
    killJobAndItChilds $parentPid
    Get-Job | Stop-Job
    Get-Job | Remove-Job
}

function Execute-PopUp(){
    $popupTitle = "Done"
    $popupScriptBlock = {
       param([string]$title)
       $wshell = New-Object -ComObject Wscript.Shell

       $wshell.Popup("Operation Completed",0,$title,0x1)
    }

    $job = Start-Job -ScriptBlock $popupScriptBlock -ArgumentList $popupTitle

    # Waiting till the popup will be up.
    # Can cause bugs if you have other window with the same title, so beaware for the title to be unique
    Do{
        $windowsTitle = Get-Process | where {$_.mainWindowTitle -eq $popupTitle }
    }while($windowsTitle -eq $null)
}

Execute-PopUp

#[YOUR SCRIPT STARTS HERE]
Write-Host "Your code"
Start-Sleep 3
#[YOUR SCRIPT ENDs HERE]


Kill-PopUp $pid

It creates your pop-up and only when the window is up (Verifying by the title. Notice that it can cause colissions if there is another process with the same window's title) your code will start run. 它会创建您的弹出窗口,并且仅在窗口启动时(通过标题进行验证。请注意,如果有另一个具有相同窗口标题的进程,它会导致分裂)您的代码将开始运行。
When your code will finish it will kill the job. 当你的代码完成后,它将终止你的工作。
Notice that I didn't use Stop-Job to stop the job. 请注意,我没有使用Stop-Job来停止工作。
I guess it because when the job created the pop-up it can't receive any commands untill the popup will be close. 我猜是因为当作业创建弹出窗口时,它无法接收任何命令,直到弹出窗口关闭。
To overcome it I kill the job's process. 为了克服它,我终止了工作的过程。

Solution #2 (using events): 解决方案#2(使用事件):

function Kill-PopUp(){
    kill (Get-Event -SourceIdentifier ChildPID).Messagedata
    Get-Job | Stop-Job
    Get-Job | Remove-Job
}

function Execute-PopUp(){
    $popupTitle = "Done"
    $popupScriptBlock = {
       param([string]$title)
       Register-EngineEvent -SourceIdentifier ChildPID -Forward
       New-Event -SourceIdentifier ChildPID -MessageData $pid > $null
       $wshell = New-Object -ComObject Wscript.Shell

       $wshell.Popup("Operation Completed",0,$title,0x1)
    }

    $job = Start-Job -ScriptBlock $popupScriptBlock -ArgumentList $popupTitle

    # Waiting till the popup will be up.
    # Can cause bugs if you have other window with the same title, so beaware for the title to be unique
    Do{
        $windowsTitle = Get-Process | where {$_.mainWindowTitle -eq $popupTitle }
    }while($windowsTitle -eq $null)
}

Execute-PopUp

#[YOUR SCRIPT STARTS HERE]
Write-Host "Your code"
Start-Sleep 3
#[YOUR SCRIPT ENDs HERE]


Kill-PopUp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM