我尝试创建一个弹出窗口,直到脚本完成才关闭。
我有以下代码来创建一个弹出框。
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("Operation Completed",0,"Done",0x1)
$wshell.quit
我以为$wshell.quit可以关闭窗口,但是它并不能。有没有一种方法可以在脚本内部关闭这个对话框而不需要用户交互?
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("Operation Completed",0,"Done",0x1)
$wshell.quit
我以为$wshell.quit可以关闭窗口,但是它并不能。有没有一种方法可以在脚本内部关闭这个对话框而不需要用户交互?
你可以在PowerShell中打开Internet Explorer,显示本地HTML页面(也称为启动画面),然后完成后关闭它。
$IE=new-object -com internetexplorer.application
$IE.navigate2("www.microsoft.com")
$IE.visible=$true
...
$IE.Quit()
还有更多的阅读材料 如何在 PowerShell 中正确关闭 Internet Explorer?
在这里使用$wshell.quit
是行不通的,因为在PowerShell中,当你执行$wshell.Popup(..)
时,会话会等待直到窗体关闭。
在窗口关闭之前,你将无法运行任何其他命令。
你可以做的是在不同的会话中创建弹出窗口,通过这样做,你可以运行你的代码,当你的代码完成后,搜索该作业并终止它。
解决方案#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
它创建您的弹出窗口,只有当窗口弹出时(通过标题验证。请注意,如果存在具有相同窗口标题的其他进程,则可能会导致冲突),您的代码才会开始运行。
当您的代码完成后,它将终止作业。
请注意,我没有使用Stop-Job停止作业。
我想这是因为当作业创建弹出窗口时,它无法接收任何命令,直到弹出窗口关闭。
为了克服这个问题,我杀死了作业的进程。
解决方案#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
请参阅https://msdn.microsoft.com/en-us/library/x83z1d9f(v=vs.84).aspx以获取参数信息。 你需要的是[nSecondsToWait],如果值为0,则脚本将无限等待,使用秒数值即可自动关闭。
intButton = wShell.Popup(strText,[nSecondsToWait],[strTitle],[nType])
另一种方法是使用wshShell.SendKeys "%N"
向对话框发送按键。
在此使用第一种方法举例说明。 我在这里使用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
nSecondsToWait
设置为1,所以弹出窗口会持续1秒。顺便说一下,在PowerShell中,你的代码看起来像这样:$wshell = New-Object -ComObject Wscript.Shell $count = 1 $result = 0 While($result -eq 0){ $result = $wshell.Popup("操作完成",1,"完成",0) # '= 1' 不确定你想要什么 $count += 1 Write-Host $count if($count -eq 10){ Exit }}
无论如何,他希望弹出窗口保持打开状态直到脚本完成。 - E235wShell.Popup(..)
,然后它将转到下一个命令,但是在PowerShell中,当您运行$wshell.Popup(..)
时,它将一直停留,直到您关闭窗体窗口,在这种情况下,您需要使用PowerShell的作业。 - E235