Правильное отображение всплывающей подсказки в PowerShell - PullRequest
8 голосов
/ 01 февраля 2010

Короткая версия : мне кажется, мне нужна помощь в правильном использовании событий в PowerShell, которые вызываются в результате сообщения Windows, чтобы избавиться от значка всплывающей подсказки.

Длинная версия :

У меня есть длительная команда PowerShell (сборка), о которой я хотел бы получать уведомление, когда она завершается с помощью всплывающей подсказки в области уведомлений / области уведомлений.

Мне удалось создать скрипт Write-BalloonTip (ниже), который примерно выполняет то, что я хочу. Единственная проблема заключается в том, что, , как это иногда происходит с иконками в трее , иконка в трее не исчезает, пока я не наведу на нее курсор мыши. Повторно используя ту же глобальную переменную для представления NotifyIcon , я могу повторно использовать этот скрипт и сохранить его так, чтобы оставался только один значок в системном трее (пока я не наведу на него курсор мыши). Это все еще похоже на взломать. Я попытался добавить обработчик событий, чтобы он получал уведомление о событии BalloonTipClosed , а затем избавлялся от него там. В обработчике событий я попробовал все три техники, которые мне предлагались, чтобы избавиться от затяжного значка, но безрезультатно.

Раздражает то, что простой .Dispose, кажется, работает при последующих вызовах сценария, что наводит меня на мысль, что блок сценария события вообще не вызывается.

Я убедился, что BalloonTipClosed вызывается после того, как подсказка исчезает в отдельном приложении WinForms.

Я что-то упустил? Буду признателен за любую оказанную помощь. Спасибо!

Вот код для «Write-BalloonTip.ps1»:

param
(
    $text,
    $title = "",
    $icon = "Info",
    $timeout=15000
)

[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | out-null

if ($global:writeBalloonTipIcon)
{
    # This gets rid of the previous one
    $global:writeBalloonTipIcon.Dispose()
}

$global:writeBalloonTipIcon = new-object System.Windows.Forms.NotifyIcon 
$global:writeBalloonTipIcon.Icon = [System.Drawing.SystemIcons]::Information

# FIXME: This *should* cleanup the icon after it's done, but it doesn't seem to work
$global:writeBalloonTipIcon.add_BalloonTipClosed(
  {
    # this *should* work, but it's not. What am I missing?
    $global:writeBalloonTipIcon.Icon = $null; 
    $global:writeBalloonTipIcon.Visible = $false; 
    $global:writeBalloonTipIcon.Dispose();
  });

$global:writeBalloonTipIcon.Visible = $true;
$global:writeBalloonTipIcon.ShowBalloonTip($timeout, $title, $text, $icon);

Ответы [ 2 ]

2 голосов
/ 01 февраля 2010

Я думаю, вам нужно выполнить этот код в потоке STA. PowerShell (показанная здесь версия 2) по умолчанию выполняется в потоке MTA:

PS U:\> [System.Threading.Thread]::CurrentThread


ManagedThreadId    : 5
ExecutionContext   : System.Threading.ExecutionContext
Priority           : Normal
IsAlive            : True
IsThreadPoolThread : False
IsBackground       : False
ThreadState        : Running
ApartmentState     : MTA
CurrentUICulture   : en-US
CurrentCulture     : en-US
Name               : Pipeline Execution Thread
1 голос
/ 01 февраля 2010

Я бы рекомендовал использовать Register-ObjectEvent для подписки на событие BalloonTipClosed. Это появилось недавно в другом SO сообщении . Проверьте это.

...