Ну, я знаю, как выполнить часть того, что вы хотите - сделать всплывающую подсказку в системном лотке, заимствуя из PowerShell. Но я не знаю, как заставить его слушать увольнение воздушного шара. Может, кто-то другой может предложить мне другое здание ответа?
В любом случае, я использую это для сценария конвертации, который я сделал для преобразования flac в mp3 в партиях. Не стесняйтесь взломать его для своих злых целей.
@echo off
setlocal
for %%I in (*.flac) do (
rem // This initiates the systray balloon.
call :systray converting from "%%~nxI" to "%%~nI.mp3"
)
goto :EOF
rem // Here's the :systray function
:systray <message>
setlocal enabledelayedexpansion
set "args=%*"
set "args=!args:'=''!"
set "code="[void] [Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms');^
$o=New-Object Windows.Forms.NotifyIcon;$o.Icon='%systemroot%\System32\PerfCenterCpl.ico';^
$o.BalloonTipIcon='Info';$o.BalloonTipText='!args!';$o.BalloonTipTitle='%~nx0';$o.Visible=1;^
$o.ShowBalloonTip(10000);Start-Sleep -M 12000;$o.Dispose();Exit""
start /b "" "powershell" %code%
endlocal & goto :EOF
В п значения в $o.ShowBalloonTip(
п)
и Start-Sleep -M
п находятся в миллисекундах. Солить по вкусу.
Update: Я нашел немного о регистрации события для $o.BalloonTipClicked
, а также lovely example in the wild. В основном, это заменить:
$o.ShowBalloonTip(10000);Start-Sleep -M 12000;$o.Dispose();Exit
... с этим:
$o.ShowBalloonTip(10000);register-objectevent $o BalloonTipClicked clicked;^
if (wait-event clicked -t 12) {$true} else {$false}; $o.Dispose(); Exit
Кроме того, необходимо выполнить powershell
в однотридовой квартире на мероприятие, чтобы работать.
start /b "" "powershell" -STA %code%
Теперь вам нужно выяснить, как сделать это актуальным в контексте вашего пакетного процесса. Во-первых, вы, вероятно, больше не сможете использовать start /b
, чтобы сделать шарообразный наконечник неблокирующим, и вы, вероятно, используете цикл for /F
для захвата вывода команды powershell
.
Добавляя к вашим заботам, я предлагаю, чтобы «выключение в xx минутах» не было полностью удобным. Что, если «Отключение через 30 минут» появилось 29 минут назад, но пользователь только что увидел его? «Выключение в 9:51 утра» может быть лучше.
Итак, имея в виду все это, поскольку то, что вы хотите, управляется событиями, а так как язык партий не обрабатывает математику с датой и временем, я предлагаю сделать всю проклятую вещь в PowerShell. Сохраните это с расширением .ps1
. Щелкните правой кнопкой мыши и запустите с помощью PowerShell. Или, если вы хотите выполнить его с консоли cmd
, сделайте powershell ".\scriptname.ps1"
.
set-executionpolicy remotesigned
if ([threading.thread]::CurrentThread.GetApartmentState() -eq "MTA") {
& powershell.exe -window minimized -sta $MyInvocation.MyCommand.Definition
exit
}
[void] [Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
$minutes = 30
$launch_time = (Get-Date).AddMinutes($minutes).ToShortTimeString()
$o = New-Object Windows.Forms.NotifyIcon
$o.Icon = "$env:SystemRoot\System32\PerfCenterCpl.ico"
$o.BalloonTipIcon = "Info"
$o.BalloonTipText = "Shutting down at $launch_time"
$o.BalloonTipTitle = "Shutdown pending..."
$o.Visible = 1
function show-balloon { $o.ShowBalloonTip($minutes * 60 * 1000) }
show-balloon
$o_hover = [Windows.Forms.MouseEventHandler]{ show-balloon }
$o.add_MouseMove($o_hover)
register-objectevent $o BalloonTipClicked clicked
if (wait-event clicked -t ($minutes * 60)) {
remove-event clicked
$o.BalloonTipText = "Have a nice day!"
$o.BalloonTipTitle = "Shutdown aborted"
$o.ShowBalloonTip(10000)
if (wait-event clicked -t 10) { remove-event clicked }
} else {
# Initiate shutdown sequence on my mark. Authorization rojo alpha 3. Mark.
stop-computer
}
unregister-event clicked
$o.Dispose()
Bill_Stewart, если вы читаете это, я знаю, что вы довольны. Как это бывает, PowerShell на данный момент является правильным инструментом для работы.
Эта информация содержится в 'HKEY_CURRENT_USER \ Software \ Classes \ Local Settings \ Software \ Microsoft \ Windows \ CurrentVersion \ TrayNotify' ... – npocmaka