Try..catch.. 在 Read-Host 期间最终失败
Try.. catch.. finally fails during Read-Host
当脚本执行 Read-Host
cmdlet 时,关闭 window 不会激活 finally
块。下面是一个任意但功能最少的示例。我正在使用 PowerShell 5.0。 Beep() 只是为了让 finally 块的执行变得明显。
try {
$value= Read-Host -Prompt "Input"
sleep 5
} finally {
[Console]::Beep(880,1000)
}
- 如果您在
Read-Host
期间通过单击红色 X 关闭 window
finally
块将不会执行。
- 如果您在
sleep
期间通过单击红色 X 关闭 window
finally
块将执行。
- 如果您在任何时候使用 Ctrl-C 中断,
finally
块将执行。
关于为什么在 Read-Host
期间关闭 window 时 finally
块没有执行,我是否缺少一些基本的东西?
完整案例涉及在 Amazon Snowball 设备上启动服务并在脚本关闭时需要停止服务。完整的案例行为反映了上面的示例案例。
编辑:由于评论说 $input 是保留变量,因此将变量从 $input 更改为 $value。不改变行为。
继续我的评论。
控制台主机有点不灵活,这取决于您在其上进行的本机操作。 'X' 与 PowerShell session/process 有关,而不是其中的代码 运行ning。因此,当您停止代码 运行 而不是 PowerShell session/process.
时,为什么 CRTL+C 会起作用
这里有一些方法可以让您考虑您的选择。
###############################################################################
#region Begin initialize environment #
###############################################################################
# Initialize GUI resources
Add-Type -AssemblyName System.Drawing,
PresentationCore,
PresentationFramework,
System.Windows.Forms,
microsoft.VisualBasic
[System.Windows.Forms.Application]::EnableVisualStyles()
###############################################################################
#endregion End initialize environment #
###############################################################################
# Prevent the MessageBox UI from closing until an entry is made
while (
($UserEntry = [Microsoft.VisualBasic.Interaction]::
InputBox('Enter a Host/User', 'Add Item')) -eq ''
)
{
[System.Windows.Forms.MessageBox]::
Show(
'Entry cannot be empty',
"Error on close" ,
0,
[System.Windows.MessageBoxImage]::Error
)
}
"You entered $UserEntry"
或用于更精细控制的完整自定义表单
# Initialize the form object
$form = New-Object System.Windows.Forms.Form
# Define form elements
$form.Text = 'Data Entry'
$txtUserInput = New-Object system.Windows.Forms.TextBox
$txtUserInput.multiline = $false
$txtUserInput.width = 120
$txtUserInput.height = 20
$txtUserInput.location = New-Object System.Drawing.Point(40,29)
$txtUserInput.Font = 'Microsoft Sans Serif,10'
$form.controls.AddRange(@(
$txtUserInput
)
)
# Evaluate form events
$form.Add_Closing(
{
param
(
$Sender,$Event
)
$result = [System.Windows.Forms.MessageBox]::Show(
'Are you sure you want to exit?',
'Close',
[System.Windows.Forms.MessageBoxButtons]::YesNo
)
if ($result -ne [System.Windows.Forms.DialogResult]::Yes)
{$Event.Cancel = $true}
})
# Start the form
$form.ShowDialog() | Out-Null
# Resource disposal
$form.Dispose()
当脚本执行 Read-Host
cmdlet 时,关闭 window 不会激活 finally
块。下面是一个任意但功能最少的示例。我正在使用 PowerShell 5.0。 Beep() 只是为了让 finally 块的执行变得明显。
try {
$value= Read-Host -Prompt "Input"
sleep 5
} finally {
[Console]::Beep(880,1000)
}
- 如果您在
Read-Host
期间通过单击红色 X 关闭 windowfinally
块将不会执行。 - 如果您在
sleep
期间通过单击红色 X 关闭 windowfinally
块将执行。 - 如果您在任何时候使用 Ctrl-C 中断,
finally
块将执行。
关于为什么在 Read-Host
期间关闭 window 时 finally
块没有执行,我是否缺少一些基本的东西?
完整案例涉及在 Amazon Snowball 设备上启动服务并在脚本关闭时需要停止服务。完整的案例行为反映了上面的示例案例。
编辑:由于评论说 $input 是保留变量,因此将变量从 $input 更改为 $value。不改变行为。
继续我的评论。
控制台主机有点不灵活,这取决于您在其上进行的本机操作。 'X' 与 PowerShell session/process 有关,而不是其中的代码 运行ning。因此,当您停止代码 运行 而不是 PowerShell session/process.
时,为什么 CRTL+C 会起作用这里有一些方法可以让您考虑您的选择。
###############################################################################
#region Begin initialize environment #
###############################################################################
# Initialize GUI resources
Add-Type -AssemblyName System.Drawing,
PresentationCore,
PresentationFramework,
System.Windows.Forms,
microsoft.VisualBasic
[System.Windows.Forms.Application]::EnableVisualStyles()
###############################################################################
#endregion End initialize environment #
###############################################################################
# Prevent the MessageBox UI from closing until an entry is made
while (
($UserEntry = [Microsoft.VisualBasic.Interaction]::
InputBox('Enter a Host/User', 'Add Item')) -eq ''
)
{
[System.Windows.Forms.MessageBox]::
Show(
'Entry cannot be empty',
"Error on close" ,
0,
[System.Windows.MessageBoxImage]::Error
)
}
"You entered $UserEntry"
或用于更精细控制的完整自定义表单
# Initialize the form object
$form = New-Object System.Windows.Forms.Form
# Define form elements
$form.Text = 'Data Entry'
$txtUserInput = New-Object system.Windows.Forms.TextBox
$txtUserInput.multiline = $false
$txtUserInput.width = 120
$txtUserInput.height = 20
$txtUserInput.location = New-Object System.Drawing.Point(40,29)
$txtUserInput.Font = 'Microsoft Sans Serif,10'
$form.controls.AddRange(@(
$txtUserInput
)
)
# Evaluate form events
$form.Add_Closing(
{
param
(
$Sender,$Event
)
$result = [System.Windows.Forms.MessageBox]::Show(
'Are you sure you want to exit?',
'Close',
[System.Windows.Forms.MessageBoxButtons]::YesNo
)
if ($result -ne [System.Windows.Forms.DialogResult]::Yes)
{$Event.Cancel = $true}
})
# Start the form
$form.ShowDialog() | Out-Null
# Resource disposal
$form.Dispose()