2016-06-12 7 views
1

Ich brauche Ballon Tipps auf zwei verschiedene Arten. 1: In meinem Hauptcode als Warnung, dass ein Konfigurationsproblem nicht richtig behoben wurde. 2: In einem separaten Jobprozess, der eine Umgebungsvariable für eine anzuzeigende Nachricht überwacht. Der Grund dafür ist, dass Autodesk Revit seine Journal-Dateien verarbeitet. Anyway ...Powershell balloonTip: Singleton Variable und Codeblock mit Start-Job?

Da ich genau das gleiche an zwei Stellen mache, macht es Sinn, eine Funktion zu haben, und vorausgesetzt, dass ich die Funktion an den Job übergeben muss, macht es Sinn, einen Codeblock zu verwenden. Ich möchte aber auch, dass jede neue Nachricht die letzte ersetzt und nicht auf eine Verblassung wartet. Also muss ich $balloonTip.Dispose verwenden. Dies funktioniert jedoch nur, wenn es nur einen globalen $ balloonTip gibt, im Grunde genommen ein Singleton. Aber es muss veränderbar sein, also macht weder $ balloonTip als Konstante noch eine Closure für den Codeblock Sinn. In diesem Beispiel verweise ich nur auf die Variable aus dem übergeordneten Bereich, aber ich frage mich, ob es einen besseren Ansatz gibt. Vor allem in Bezug auf einen Job. Oder schafft ein Job per definitionem einen völlig anderen Bereich ohne die Chance auf gemeinsame Variablen, und ich sollte das gleiche Szenario nur innerhalb des Jobs implementieren. Funktionell funktioniert das, da ein vom Auftrag gesteuerter ballonTip niemals angezeigt wird, wenn der Fehler bt angezeigt wird. In der Tat wird der Job nie erstellt. Aber das ist spezifisch für diese Implementierung, und ich stelle mir eine Situation vor, in der ich wirklich einen einzigen $ balloonTip haben möchte, der sogar von zwei verschiedenen Jobs angetrieben wird.

Add-Type -assemblyName:System.Windows.Forms 
$balloonTip = New-Object System.Windows.Forms.NotifyIcon 


    $messageArguments = @{ 
     icon = [System.Drawing.Icon]::ExtractAssociatedIcon($(Get-Process -id:$pid | Select-Object -expandProperty:Path)) 
     btIcon = 'Info' 
     btTitle = 'Test' 
     btText = "$env:userName $(Get-Date)" 
    } 


    $sendMessage = { 
     param (
      [System.Drawing.Icon]$icon, 
      [String]$btIcon, 
      [String]$btTitle, 
      [String]$btText 
     ) 

     $balloonTip.Dispose 

     $balloonTip.Icon = $icon 
     $balloonTip.balloonTipIcon = $btIcon 
     $balloonTip.balloonTipTitle = $btTitle 
     $balloonTip.balloonTipText = $btText 

     $balloonTip.visible = $true 
     $balloonTip.showBalloonTip(0) 
    } 

    $a=0 
    do { 
     & $sendMessage @messageArguments 
     Start-Sleep -s:3 
    } While (++$a -le 5) 

Und nicht nur PetSerAl die Frage zu beantworten, aber auf meinem eigenen erweitern, habe ich dieses Stück Code, dass ich dachte funktionieren würde, mit dem $ Balloontip Variable im Job Umfang haben würde. Aber es scheint nicht zu funktionieren. Und das Problem liegt wahrscheinlich im übergebenen Codeblock, also habe ich den Titel überarbeitet, um die erweiterte Frage widerzuspiegeln.

$sendMessage = { 
    param (
     [System.Drawing.Icon]$icon, 
     [String]$btIcon, 
     [String]$btTitle, 
     [String]$btText 
    ) 

    $balloonTip.Icon = $icon 
    $balloonTip.balloonTipIcon = $btIcon 
    $balloonTip.balloonTipTitle = $btTitle 
    $balloonTip.balloonTipText = $btText 

    $balloonTip.visible = $true 
    $balloonTip.showBalloonTip(0) 
} 


function Start-MessageJob { 
    [CmdletBinding()] 
    param ( 
     [Int]$id, 
     [ScriptBlock]$sendMessage 
    ) 

    Start-Job -name:Messages -argumentList:@($id, $sendMessage) -scriptBlock { 
     param ( 
      [Int]$id, 
      [ScriptBlock]$sendMessage 
     ) 

     Add-Type -assemblyName:System.Windows.Forms 

     if ($balloonTip) { 
      $balloonTip.Dispose 
     } else { 
      $balloonTip = New-Object System.Windows.Forms.NotifyIcon 
     } 

     $messageArguments = @{ 
      icon = [System.Drawing.Icon]::ExtractAssociatedIcon($(Get-Process -id:$id | Select-Object -expandProperty:Path)) 
      btIcon = 'Info' 
      btTitle = 'Test' 
      btText = $null 
     } 


     do { 
      $messageArguments.btText = "$env:userName $(Get-Date)" 
      & $sendMessage @messageArguments 
      Start-Sleep -s:5 

     } while (Get-Process -id:$id -errorAction:silentlyContinue) 
    } > $null 
} 


Start-MessageJob -id:$pid -sendMessage:$sendMessage 
+0

Was halten Sie * von * Job bedeuten angezeigt werden? Sprechen Sie über Hintergrundjobs ('Start-Job')? – PetSerAl

+2

'Start-Job' erzeugt einen separaten PowerShell-Prozess, um den Job zu hosten. Sie benötigen verschiedene Arten von Jobs, wenn Sie ein Live-Objekt (wie 'NotifyIcon') zwischen ihnen teilen möchten. – PetSerAl

+0

Welche Art von "Job" in diesem Fall? Und, irgendwelche Gedanken in der zweiten Charge von Code? In diesem Beispiel versuche ich nicht, die $ balloonTip-Variable zu teilen, sondern übergebe den eigentlichen Balloon Tip-Code-Block, und das scheint nicht zu funktionieren. – Gordon

Antwort

0

Ich schreibe diesen Code popUp

function Show-BalloonTip { 
    [CmdletBinding(SupportsShouldProcess = $true)] 
    param 
    (
     [Parameter(Mandatory=$true)] 
      $Title, 
     [Parameter(Mandatory=$true)] 
      $Text, 
     [ValidateSet('None', 'Info', 'Warning', 'Error')] 
      $Icon = 'Info', 
      $Timeout = 10000 
    ) 
    remove-Job -Name BalloonTip -State Completed -ea 0 
    Start-Job -name BalloonTip -ScriptBlock { 
    param ($Title, $Text, $Icon, $Timeout) 
     Add-Type -AssemblyName System.Windows.Forms 

     $balloon = New-Object System.Windows.Forms.NotifyIcon 

     switch($icon){ 
      Warning { 
       $balloon.Icon = [System.Drawing.SystemIcons]::Warning 
       Write-Host "$([char]7)" # beep sound 
      } 
      Error { 
       $balloon.Icon = [System.Drawing.SystemIcons]::Error 
       Write-Host "$([char]7)" # beep sound 
      } 
      default { 
       #Define the icon for the system tray 
       $balloon.Icon = [System.Drawing.SystemIcons]::Information 
      } 
     } 
     #Type of balloon icon 
     $balloon.BalloonTipIcon = $Icon 

     #Display title of balloon window 
     $balloon.BalloonTipTitle = $Title 
     #Notification message 
     $balloon.BalloonTipText = $Text 
     #Make balloon tip visible when called 
     $balloon.Visible = $True 
     #Call the balloon notification 
     $balloon.ShowBalloonTip($Timeout) 
     Start-Sleep -Milliseconds $Timeout 
     $balloon.Dispose() 
    } -ArgumentList @($Title, $Text, $Icon, $Timeout) 
}