PowerShell取消按钮停止脚本

时间:2014-03-18 14:04:01

标签: forms powershell button exit powergui

我遇到了一些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.
}

感谢您的帮助

1 个答案:

答案 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()
}