【问题标题】:PowerShell form not displaying when screen is locked屏幕锁定时不显示 PowerShell 表单
【发布时间】:2020-12-26 09:14:03
【问题描述】:

我正在使用 PowerShell 表单来提示用户关闭 Adob​​e Reader,以便对其进行升级。它通过 SCCM 执行,因此在系统上下文中运行。如果用户登录并且会话处于活动状态,则它可以工作,但是如果屏幕被锁定,当我解锁屏幕时,表单不会显示,尽管脚本正在运行。

我最初使用$Form.ShowDialog() 显示它,但看到其他一些帖子说它不可靠,所以我切换到[void][System.Windows.Forms.Application]::Run($Form) 但它仍然不起作用。谁能帮我解决这个问题?

以下是精简后的脚本,其中仅包含与呈现表单相关的代码。

Add-Type -AssemblyName System.Windows.Forms, System.Drawing
$Font = New-Object System.Drawing.Font('Segoe UI Light',14,[System.Drawing.FontStyle]::Regular)
$FontBold = New-Object System.Drawing.Font('Segoe UI',13,[System.Drawing.FontStyle]::Bold)

Function EndForm
{
    $Timer.Stop();
    $Timer.Dispose();
    $Label.Dispose();
    $CountdownLabel.Dispose();
    $ProgressBar.Dispose();
    $OKButton.Dispose();
    $Form.Close();
    $Form.Dispose();
}

$OnOKClick =
{
    $MsgBoxInput = [System.Windows.Forms.MessageBox]::Show("Are you sure you want to close and uninstall Adobe Reader now?","Confirm Adobe Reader Removal","YesNo","Warning")
    If ($MsgBoxInput -eq "Yes") {EndForm}
}

$Script:Countdown = 3600
$OKToolTip = "Click OK to close and uninstall Adobe Reader now"
$CountdownSubtitle = "Adobe Reader will close and uninstall in"

$Label = New-Object System.Windows.Forms.Label
$Label.AutoSize = $False
$Label.Height = 120
$Label.Width = 630
$Label.Font = $Font
$Label.BackColor = "White"
$Label.ForeColor = "#4D4C5C"
$Label.Location = New-Object System.Drawing.Size(52,180)
$Label.Text = "Your computer will soon be upgraded to newer versions of Windows 10 and Office 365. In order to succeed, the upgrade process requires that Adobe Reader be closed and uninstalled first. It will not be available for use again until after the upgrade has completed."

$CountdownLabel = New-Object System.Windows.Forms.Label
$CountdownLabel.AutoSize = $False
$CountdownLabel.Height = 40
$CountdownLabel.Width = 530
$CountdownLabel.Font = $Font
$CountdownLabel.BackColor = "White"
$CountdownLabel.ForeColor = "#4D4C5C"
$CountdownLabel.Location = New-Object System.Drawing.Size(120,380)

$ProgressBar = New-Object System.Windows.Forms.ProgressBar
$ProgressBar.Location = New-Object System.Drawing.Size(52,340)
$ProgressBar.Size = New-Object System.Drawing.Size(635,35)
$ProgressBar.Style = "Continuous"
$ProgressBar.Maximum = $Script:Countdown
$ProgressBar.Minimum = 0

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Name = "OK_Button"
$OKButton.Size = New-Object System.Drawing.Size(80,40)
$OKButton.Location = New-Object System.Drawing.Size(330,450)
$OKButton.UseVisualStyleBackColor = $True
$OKButton.Text = "OK"
$OKButton.DataBindings.DefaultDataSourceUpdateMode = 0
$OKButton.Add_Click($OnOKClick)

$ToolTip = New-Object System.Windows.Forms.ToolTip
$ToolTip.IsBalloon = $False 
$ToolTip.InitialDelay = 100 
$ToolTip.ReshowDelay = 200 
$ToolTip.SetToolTip($OKButton,$OKToolTip) 

$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Contoso LLC"
$Form.Font = $Font
$Form.Width = 770
$Form.Height = 580
$Form.MinimizeBox = $False
$Form.MaximizeBox = $False
$Form.ControlBox = $False
$Form.ShowIcon = $False
$Form.WindowState = "Normal"
$Form.FormBorderStyle = "Fixed3D"
$Form.ShowInTaskbar = $True
$Form.StartPosition = "CenterScreen"
$Form.Topmost = $True
$Form.Controls.Add($ProgressBar)
$Form.Controls.Add($Label)
$Form.Controls.Add($CountdownLabel)
$Form.Controls.Add($OKButton)

$Timer = New-Object System.Windows.Forms.Timer
$Timer.Interval = 1000
$Timer.Add_Tick(
{
    If ($Script:Countdown -eq 0) {EndForm}

    $ProgressBar.Value  = $Script:Countdown
    $TimeRemain = New-Timespan -Seconds $Script:Countdown
    $HrsRemain = $TimeRemain.Hours
    $MinsRemain = $TimeRemain.Minutes
    $SecsRemain = $TimeRemain.Seconds

    If ($HrsRemain -ge 2) {$HrsText = "$HrsRemain hours"}
    If ($HrsRemain -eq 1) {$HrsText = "$HrsRemain hour"}
    If ($MinsRemain -ge 2) {$MinsText = "$MinsRemain minutes"}
    If ($MinsRemain -eq 1) {$MinsText = "$MinsRemain minute"}
    If ($SecsRemain -ge 2) {$SecsText = "$SecsRemain seconds"}
    If ($SecsRemain -eq 1) {$SecsText = "$SecsRemain second"}

    $CountdownLabel.Text  = "$CountdownSubtitle $HrsText $MinsText $SecsText"

    If ($HrsRemain -ge 1 -And $MinsRemain -eq 0) {$CountdownLabel.Text = "$CountdownSubtitle $HrsText $SecsText"}
    If ($HrsRemain -eq 0) {$CountdownLabel.Text = "$CountdownSubtitle $MinsText $SecsText"}
    If ($HrsRemain -eq 0 -And $MinsRemain -eq 0) {$CountdownLabel.Text = "$CountdownSubtitle $SecsText"}
    $Script:Countdown--
})

$Timer.Start()
[void][System.Windows.Forms.Application]::Run($Form)

【问题讨论】:

  • 嗨,我从来没有说过我希望表单显示在锁定屏幕的顶部。我很高兴它在屏幕锁定时在后台运行。这只是为了以防用户在表单出现时离开他们的办公桌,并且他们碰巧在倒计时结束之前解锁了他们的屏幕。在这种情况下,如果他们使用的是 Adob​​e Reader,它将在没有警告的情况下停止,虽然这不是世界末日,但可能会产生不理想的帮助台事件。我宁愿不争论我为什么这样做的逻辑,我更愿意专注于提出解决方案。谢谢。
  • 至于需要以用户身份登录,这是不正确的。此表单在通过 SCCM 部署时显示完美,正如我所说,它在系统上下文中运行(尽管有一个选项可以在用户上下文中运行它 - 我没有设置)。
  • 好的,使用此说明删除了其他 cmets,但您正在向当前登录的用户发送 GUI。所以,它必须在用户的上下文中才能看到。 PowerShell 仅运行/输出到启动它的用户上下文。
  • 我实际上认为我可能已经通过将锁定屏幕视为与注销用户相同的方式来“解决”它,因此在这种情况下只需结束 Adob​​e Reader。使用登录进程作为决定因素。我会测试它,看看是否有帮助。当然,这并不理想,但它可以工作 - 至少 Adob​​e Reader 不会在他们眼前关闭,他们会想知道发生了什么。
  • 很好,如果 SCCM 方法是一种 catch22,我的下一个建议是通过计划任务使用登录检查,并在用户屏幕解锁时触发脚本以弹出 UI。是的,如果他们只是在阅读 PDF

标签: forms powershell locking screen display


【解决方案1】:

我决定通过检测是否存在登录进程来“解决”这个问题,这意味着屏幕被锁定。在这种情况下,我还是直接关闭 Adob​​e Reader。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多