我有一个 Powershell 脚本,它负责启动备份软件,并由系统用户下的计划任务启动。我不能使用用户会话,因为我需要在磁盘上拥有完全的管理员权限,并且即使没有用户登录也要运行备份。
我想在任务栏中显示通知和图标以具有视觉指示器,并尽可能避免在备份过程中关闭计算机。
所以我在 Powershell 脚本中放入以下代码来创建通知:
$iconPath = "C:\icon.ico"
$icon = New-Object System.Drawing.Icon $iconPath
$notification = New-Object System.Windows.Forms.NotifyIcon
$notification.Icon = $icon
$notification.Visible = $true
$notification.ShowBalloonTip(5000, "Burp backup started", "", [System.Windows.Forms.ToolTipIcon]::Info)
#... backup starting commands
$notification.ShowBalloonTip(5000, "Burp backup finished", "", [System.Windows.Forms.ToolTipIcon]::Info)
$notification.Dispose()
问题是定时任务启动脚本时没有出现通知(但手动启动脚本时可以正常工作)
我猜这是因为启动任务的用户是系统,所以它没有会话的桌面/资源管理器上下文来显示界面。
有没有办法将通知附加到登录的用户会话? 知道在我的情况下,计算机上只有一个用户,而且我知道要搜索的用户名。
您的要求阻止了一个简单的解决方案:
您声明无论用户是否登录,您的任务都必须运行,这总是使其在会话
0
中运行,即服务运行的隐藏窗口站。
Session
0
进程可以not 直接与登录用户的桌面交互,需要一个indirect - 繁琐的解决方案;来自Interactive Services(注释;强调):
您可以使用以下技术与用户进行交互 所有支持的 Windows 版本上的服务:
在用户会话中显示一个对话框 功能。WTSSendMessage
函数在上下文中运行应用程序 交互式用户。设计用于通信的 GUI 应用程序 通过某种进程间通信的方法与服务 (IPC),例如命名管道。该服务与 GUI 通信 应用程序告诉它何时显示 GUI。应用程序 将用户交互的结果传回服务 以便服务可以采取适当的行动。请注意,IPC 可以 在网络上公开你的服务接口,除非你使用 适当的访问控制列表 (ACL)。CreateProcessAsUser
.
如果此服务在多用户系统上运行,请将应用程序添加到 以下键,以便它在每个会话中运行:。如果 应用程序使用命名管道进行 IPC,服务器可以区分 通过给每个管道一个唯一的名称在多个用户进程之间 基于会话 ID。HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run