我遇到了一些PS GUI功能问题。
我已经尝试过很多东西并一直在寻找(所有的链接都是紫色的!)。
我的表单上有一个取消按钮,现在当用户点击取消按钮时,它指向此处理程序,我的表单将关闭。
$handler_cancelButton_Click={
$MainForm.Close()
}
然而,一旦表单关闭,我脚本的所有其余部分都会尝试继续运行(FTP,运行Excel,发送电子邮件等)并且会引发错误。
我尝试了很多不同的东西,我只运行了Exit
命令并关闭了我的表单,抛出了一个错误,并关闭了我的整个IDE(PowerGUI)。
现在我也尝试过这样的事情:
[environment]::exit(0)
[System.Windows.Forms.Application]::Exit($null)
两者都将完全按照Exit
进行调用。关闭我的表单和PowerGUI。
我想要发生的是当用户按下取消,我的表单关闭,我的脚本的其余部分停止或终止。
编辑
现在我有一个GUI.ps1和一个Code.ps1。我想我会在Code.ps1中调用GUI.ps1,获取我需要的用户输入到变量中。然后获取这些变量并将它们从GUI.ps1传递到Code.ps1(我需要该信息才能在此处运行任何内容)。
然后,当我在Code.ps1中拥有这些值时,运行我正在做的其他所有事情。?
但是现在如果我的用户出于某种原因决定只点击取消按钮......
(说实话,可能不会发生很多事情,我更希望让这个功能为了学习而工作。他们可能会意外地运行脚本,不知何故......)
...它只会关闭GUI,但Code.ps1的其余部分是否仍会运行?
或者现在我可以在我的Code.ps1脚本中说出类似的内容:
if($someGUIValue -eq $null -and $someOtherGUIValues - eq $null){
Exit #would I be able to run this now the way I think it would?
}
else{
#yes, run the script..
}
* *找到答案
修改 ..
我做的是创造了一面旗帜。在我的任何脚本开始之前,我声明了一个像这样的变量
$terminateScript = $false
在我的事件处理程序中,我添加了这个
$handler_cancelButton_Click={
$terminateScript = $true
$MainForm.Close()
return $terminateScript
}
点击取消按钮后,它会设置$terminateScript = $true
。所以现在我在调用我的所有函数时,我有类似的东西:
$username, $password, $someOtherValue, $anotherVaklue, $terminateScript = MainForm
if($terminateScript -eq $false){
SomeFunction
AnotherFunction
}
else{
Exit #this now works here, and cancels my script, without closing my IDE.
}
感谢您的帮助
答案 0 :(得分:2)
PowerShell正在完成它的设计目标。 PowerShell是一个脚本环境,可以启动多个单独的程序,而不像使用可以终止的单个线程运行的C#程序。
从PowerShell启动的每个进程都在其自己的进程中单独启动。没有一个命令可以结束所有进程。相反,您必须处理打开的所有进程,并关闭每个进程。
$MainForm.Close()
将关闭GUI。它没有关闭任何其他东西。
Exit
将退出整个PowerShell提示符。如果您已经启动了像Excel这样的可执行文件,它仍将在其自己的进程中打开。
如果要启动Excel之类的东西,则必须使用句柄将其关闭:
#create Excel object
$Excel = New-Object -comobject Excel.Application
#.... do stuff...
#Close Excel
$Excel.quit()
[Runtime.Interopservices.Marshal]::ReleaseComObject($excel) # Release COM
Remove-Variable excel # Remove the Variable
同样,如果您使用Start-Process
启动记事本等流程,则可以使用-Passthru
参数获取句柄以便关闭它:
#Run process
$Handle = Start-Process notepad.exe -PassThru
#.... do stuff...
#End process
$Handle | Stop-Process
所以,如果你想让你的脚本退出"退出"你必须跟踪你正在打开的所有内容,关闭它们,停止其他脚本,结束所有生成的进程......然后最终关闭你的GUI。
<强> - 编辑--- 强>
回复你的评论:
确定。如果我理解你,请忽略我上面所说的。您基本上希望GUI显示,提供运行其余脚本的选项,并退出(不继续并运行脚本的其余部分)或继续运行脚本的其余部分。
您遇到的问题是PowerShell如何加载脚本。首先,它创建表单,创建按钮,然后创建事件处理程序以处理按钮单击,并显示表单。然后继续运行脚本的其余部分。因为您使用Windows窗体创建GUI,所以它是非阻塞的,即在继续之前它不会停止执行脚本以等待您的输入。阻塞命令的一个示例是Read-Host
命令:
$Response = Read-Host -Prompt "Do I continue (y/n)?"
...哪会停止当前脚本的执行,如果你想继续则提示。然后继续然后,您可以使用简单的if语句来处理是否继续并运行脚本的其余部分:
if($Response -eq "y")
{
#Run rest of script
}
#else the script ends and you do nothing.
如果您想使用GUI(如Windows窗体)处理它,那么最简单的方法是将代码分成两部分。
第一部分(GUI.ps1)是您的GUI。它只是显示提示,然后脚本完成。 (请记住,GUI已创建,并在脚本完成执行后继续运行)
第二部分(Code.ps1)是您希望它执行的代码。
在GUI代码中,您有2个按钮和2个处理程序,您可以使用&#34;运行&#34;按钮,和你的&#34;取消&#34;按钮。
你的&#34;运行&#34;按钮代码是:
$handler_RunButton_Click={
#Run Code script
. .\Code.ps1
}
你的&#34;取消&#34;按钮与您目前拥有的代码相同:
$handler_cancelButton_Click={
$MainForm.Close()
}