在Powershell中创建弹出消息 [英] Create a popup message in Powershell
问题描述
我正在尝试创建一个允许我弹出的功能,请稍等消息,再运行一些脚本,然后关闭弹出窗口
I'm attempting to make a function that will allow me to popup a please wait message run some more script then close the popup
Function Popup-Message {
param ([switch]$show,[switch]$close)
Add-Type -AssemblyName System.Windows.Forms
# Build Form
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Test"
$objForm.Size = New-Object System.Drawing.Size(220,100)
# Add Label
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(80,20)
$objLabel.Size = New-Object System.Drawing.Size(100,20)
$objLabel.Text = "Hi there!"
$objForm.Controls.Add($objLabel)
If ($show)
{
$objForm.Show() | Out-Null
$global:test = "Show"
}
If ($close)
{
# destroy form
$objForm.Close() | Out-Null
$global:test = "Close"
}
}
然后我可以通过以下方式显示弹出窗口:
I can then get the popup to display by:
Popup-Message -show
这时,我可以看到 $ test 变量为显示
At this point I can see the $test variable as Show
但是当我尝试使用以下方法关闭窗口时:
But when I try to close the window with:
Popup-Message -close
但是弹出窗口不会关闭如果我再次查看 $ test ,它将显示为关闭
But the popup window will not close If I look at $test again it will show as Close
我假设这与将函数保留在Global Scope中有关,但是我不知道如何使用表单
I'm assuming this has something to do with keeping the function in the Global Scope but I can't figure out how to do this with the form
推荐答案
kpogue的有用答案可以很好地说明您的问题并提供一种有效的解决方案,但由于依赖全局变量而不够理想.
kpogue's helpful answer explains your problem well and offers a solution that is effective, but suboptimal due to relying on global variables.
让我建议一种不同的方法,在该方法中,您使用函数简单地定义表单并返回该定义,您可以在其中调用 .Show()
和 .Close()
方法 ,但请注意, .Show()
方法通过 添加成员
包含对 [System.Windows.Forms.Application] :: DoEvents()
的调用,以确保正确绘制表单.
Let me suggest a different approach, where you use a function to simply define the form and return that definition, on which you can call the .Show()
and .Close()
methods as needed, but note that the .Show()
method is overridden via Add-Member
to include a call to [System.Windows.Forms.Application]::DoEvents()
, so as to ensure that the form is properly drawn.
function New-PopUpForm {
Add-Type -AssemblyName System.Windows.Forms
# Create the form.
$objForm = New-Object System.Windows.Forms.Form -Property @{
Text = "Test"
Size = New-Object System.Drawing.Size 220, 100
StartPosition = 'CenterScreen' # Center on screen.
FormBorderStyle = 'FixedSingle' # fixed-size form
# Remove interaction elements (close button, system menu).
ControlBox = $false
}
# Create a label...
$objLabel = New-Object System.Windows.Forms.Label -Property @{
Location = New-Object System.Drawing.Size 80, 20
Size = New-Object System.Drawing.Size 100, 20
Text = "Hi there!"
}
# ... and add it to the form.
$objForm.Controls.Add($objLabel)
# Override the `.Show()` method to include
# a [System.Windows.Forms.Application]::DoEvents(), so as
# to ensure that the form is properly drawn.
$objForm | Add-Member -Force -Name Show -MemberType ScriptMethod -Value {
$this.psbase.Show() # Call the original .Show() method.
# Activate the form (focus it).
$this.Activate()
[System.Windows.Forms.Application]::DoEvents() # Ensure proper drawing.
}
# Since this form is meant to be called with .Show() but without
# a [System.Windows.Forms.Application]::DoEvents() *loop*, it
# it is best to simply *hide* the cursor (mouse pointer), so as not
# to falsely suggest that interaction with the form is possible
# and so as not to end up with a stuck "wait" cursor (mouse pointer) on
# the first instantiation in a session.
[System.Windows.Forms.Cursor]::Hide()
# Return the form.
return $objForm
}
然后可以按如下方式使用该功能:
You can then use the function as follows:
$form = New-PopupForm
$form.Show()
# ...
$form.Close()
注意:
-
一旦调用
.Close()
,存储在$ form
中的表单实例将被处理并且无法重复使用-只需调用New-再次使用PopupForm
创建一个新实例.
Once you call
.Close()
, the form instance stored in$form
is disposed of and cannot be reused - simply callNew-PopupForm
again to create a new instance.
如果运行您的脚本 的PowerShell会话退出,则该会话中创建的所有弹出窗口都会自动关闭.
If the PowerShell session running your script exits, any pop-up windows created in the session close automatically.
注意事项:
-
请注意,由于使用
.Show()
方法(无需额外的努力),用户将无法进行交互并带有弹出窗口,尤其是甚至没有为了移动窗口或手动关闭窗口.
Note that, due to use of the
.Show()
method (without additional effort), the user won't be able to interact with the pop-up window, notably not even in order to move the window or close it manually.
- 如果(例如在您的情况下)窗口不是要与之交互的,那么这不是问题.
- 在上面设置
ControlBox = $ false
会删除窗口的关闭按钮和系统菜单,从而明显表明无法进行交互. - 使用
[System.Windows.Forms.Cursor] :: Hide()
隐藏光标(鼠标指针)具有相同的目的.- 注意:不隐藏光标会导致等待".在将鼠标悬停在表单上时无限期地显示光标(指示该表单正在忙于处理某件事),但奇怪的是,仅针对会话中创建的第一个实例显示.如我所知,避免这种情况的唯一方法是在调用
.Show()
之后进入事件循环,如上一个要点所述.
- If, such as in your case, the window isn't meant to be interacted with, this isn't a problem, however.
- Setting
ControlBox = $false
above removes the window's close button and system menu so as to make it obvious that no interaction is possible. - Hiding the cursor (mouse pointer) with
[System.Windows.Forms.Cursor]::Hide()
serves the same purpose.- Note: Not hiding the cursor causes the "wait" cursor to be shown (indicating that the form is busy processing something) indefinitely while mousing over the form, but curiously only for the very first instance created in a session. The only way to avoid it that I know of is to enter an event loop after calling
.Show()
, as discussed in the last bullet point.
相反,
.ShowDialog()
将允许交互,但会阻止脚本的进一步执行 ,直到用户关闭窗口.By contrast,
.ShowDialog()
would allow interaction, but blocks further execution of your script until the window is closed by the user.如果您需要组合这两种方法-允许用户与窗口交互,同时继续在PowerShell脚本中进行处理-您需要循环调用
[System.Windows.Forms.Application] :: DoEvents()
,如If you need to combine the two approaches - allowing the user to interact with the window while continuing to do processing in your PowerShell script - you need to call
[System.Windows.Forms.Application]::DoEvents()
in a loop, as shown in this answer.- 如果使用这种方法,则应从函数中删除
[System.Windows.Forms.Cursor] :: Hide()
调用.
这篇关于在Powershell中创建弹出消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- Note: Not hiding the cursor causes the "wait" cursor to be shown (indicating that the form is busy processing something) indefinitely while mousing over the form, but curiously only for the very first instance created in a session. The only way to avoid it that I know of is to enter an event loop after calling
- 注意:不隐藏光标会导致等待".在将鼠标悬停在表单上时无限期地显示光标(指示该表单正在忙于处理某件事),但奇怪的是,仅针对会话中创建的第一个实例显示.如我所知,避免这种情况的唯一方法是在调用