DJ *_*res 19 powershell winforms powershell-4.0
我这里有一个有趣的问题.我正在创建一个日历选择器,供我们创建帐户时使用.它工作正常并且仍在进行中但是我注意到当我在powershell ISE中运行脚本时,几分钟后它就会锁定(我能够在此之前编辑并保存代码几分钟).事件日志中没有任何内容.我得到一个对话框,说PowerShell没有响应.内存使用情况也很正常.我不知道发生了什么.
无论我如何运行Powershell ISE(以管理员身份运行,作为另一个帐户运行,以及正常的ISE),我都会运行Windows 8.1.
同事建议它可能是公寓型号,所以我尝试了STA和MTA,但问题出现了.从控制台主机运行相同的代码时不会发生这种情况.
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$objForm = New-Object Windows.Forms.Form
$objForm.Text = "Select a Date"
$objForm.Size = New-Object Drawing.Size @(490,250)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview = $True
$objForm.Add_KeyDown({
if ($_.KeyCode -eq "Enter")
{
$script:dtmDate=$objCalendar.SelectionStart
$objForm.Close()
}
})
$objForm.Add_KeyDown({
if ($_.KeyCode -eq "Escape")
{
$objForm.Close()
}
})
$objCalendar = New-Object System.Windows.Forms.MonthCalendar
$objCalendar.Text = "Start"
$objCalendar.ShowTodayCircle = $False
$objCalendar.MaxSelectionCount = 1
$objForm.Controls.Add($objCalendar)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
if ($dtmDate)
{
Write-Host "Date selected: $dtmDate"
}
$objForm.Dispose()
Run Code Online (Sandbox Code Playgroud)
回应@The Unique Paul Smith
function Find-CalenderDateTest {
[CmdletBinding()]
param(
[Parameter(
Mandatory=$false
)]
[ValidateSet('long','short','powerpoint')]
[ValidateNotNullOrEmpty()]
[string]
$DateFormat
)
Begin{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$objForm = New-Object Windows.Forms.Form
$objForm.Text = "Select a Date"
$objForm.Size = New-Object Drawing.Size @(243,250)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview = $True
$dtmDate = $null
$objForm.Add_KeyDown( {
if ($_.KeyCode -eq "Enter")
{
$dtmDate=$objCalendar.SelectionStart
$objForm.Close()
}
})
$objForm.Add_KeyDown({
if ($_.KeyCode -eq "Escape")
{
$objForm.Close()
}
})
#region OK Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(20,175)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
# Got rid of the Click event for OK Button, and instead just assigned its DialogResult property to OK.
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$objForm.Controls.Add($OKButton)
# Setting the form's AcceptButton property causes it to automatically intercept the Enter keystroke and
# treat it as clicking the OK button (without having to write your own KeyDown events).
$objForm.AcceptButton = $OKButton
#endregion
#region Cancel Button
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(80,175)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
# Got rid of the Click event for Cancel Button, and instead just assigned its DialogResult property to Cancel.
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$objForm.Controls.Add($CancelButton)
# Setting the form's CancelButton property causes it to automatically intercept the Escape keystroke and
# treat it as clicking the OK button (without having to write your own KeyDown events).
$objForm.CancelButton = $CancelButton
#endregion
$objCalendar = New-Object System.Windows.Forms.MonthCalendar
$objCalendar.ShowTodayCircle = $False
$objCalendar.MaxSelectionCount = 1
$objForm.Controls.Add($objCalendar)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
$Results = $objForm.ShowDialog()
}
Process{}
End{
if ($Results -eq "OK")
{
$objCalendar.SelectionStart
}
$objForm.Dispose()
}
}
Run Code Online (Sandbox Code Playgroud)
虽然可能性不大,但问题可能是 powershell 未正确关闭 $objForm 对象,使其在脚本终止后 ISE 等待输入时在内存中运行。如果您检查任务管理器,该表单是否仍在后台运行?您还可以尝试在 dispose() 之后添加“Remove-Variable objForm”(无 $),看看是否有帮助。
更多信息:https ://technet.microsoft.com/en-us/library/ff730962.aspx
正如我所说,这是一个长远的目标。