Posts tagged: NotificationIcon

PowerShell module BalloonNotification – hvordan utvikle moduler med C# og VisualStudio 2012

By , 8 oktober, 2012 01:38

Balloon en pest og plage?

«Windows Ballooning» eller «NotifyIcon» oppleves av mange som en pest og plage, men de små beskjedene har også sin nytte. Selv har jeg benyttet «bobla» til å informere sluttbruker om viktige hendelser knyttet til logonscript, eller for å vise maskininformasjon slik som IP-adresse, domene- og maskinnavn.

Denne bloggposten gir hjelp til hvordan man kan lage C# PowerShell moduler i Visual Studio 2012 Express. Modulen BalloonNotification er benyttet som eksempel og kildekode.


Demo av PowerShell modulen BalloonNotification

PowerShell eller C# som språk ved utvikling av moduler

PowerShell er et kraftfullt språk. Som PowerShell fantast er min anbefaling at man også velger å utvikle moduler med PowerShell som språk så langt det er mulig. Likevel har jeg denne gang valgt å skrive modulen i C# med Visual Studio 2012. Årsaken var behov for enklere håndtering av klassen NotifyIcon. Samtidig hadde jeg også stor nysgjerrighet på C# og Visual Studio 2012. Jeg er ingen utvikler og C# er et språk jeg ikke benytter i det daglige. Dere som kan programering og C# får ha meg unnskylt.

Det er også mulig å kjøre C# i PowerShell, men det det kan på grunn av kompilering under kjøring av script oppleves som tregt. Jeg pleier derfor å kompliere koden først og importere denne som modul i PowerShell. (Det en fordel med god kildekode og versjonskontroll for senere iterasjoner). Typisk vil man komme i situasjoner hvor man ønsker å legge til GUI i script og C# eller andre lignende språk kan være enklere å jobbe med, for eksempel gjennom å lage en modul for PowerShell.

NotifyIcon
Klassen NotifyIcon tilhører System.Windows.Forms og er komponenten som håndterer ikon i systemstatusfeltet (http://msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon.aspx). NotifyIcon klassen kan i likhet med andre .net klasser også benyttes i PowerShell, for eksempel gjennom følgende:

[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
$notification = New-Object System.Windows.Forms.NotifyIcon

Hvordan komme i gang med C# PowerShell modulprosjekt i Visual Studio 2012

Før man begynner utvikling av PowerShell modul i C# bør man installere Windows PowerShell 2.0 Software Development Kit (SDK) – http://www.microsoft.com/en-us/download/details.aspx?id=2560
I eksemplet skal vi benytte System Management Automation.

Opprettelse av Visual Studio 2012 PowerShell module prosjekt

  1. Opprett nytt prosjekt - for eksempel «File | New Project…» eller velg » New Project» under «Start Page»
  2. I vinduet «New Project» velg «Visual C# | Windows | Class Library«. Skriv inn ett passende navn i «Name» og «Soultion name«, samt angi plassering under «Location»

    New Project Visualt Studio 2012

  3.  

  4. Nye prosjekter i Visual Studio 2012 blir opprettet i .NET 4.0. Vi må endre dette til .NET Framework 3.5 slik at PowerShell 2.0 kan laste modulen.
    Under «Solution Explorer» høyreklikk «BalloonNotification» (eller ditt C# prosjektnavn) og velg «Properties«. Under vinduet «Application» velg «Target Framework | .Net Framework 3.5.»
    Net Framework 3.5

    Net Framework 3.5

  5. Det må legges til to PowerShell «References» – System.Management og System.Management.Automation.
    Høyreklikk «References» og velg «Add«. Legg til nødvendige references. Man må selv lokalisere og velge Windows.Management.Automation.dll i PowerShell SDK installasjonsmappen. Legg også til eventuelle andre References etter behov og etter hva du skal benytte i din modul.
    References

    References

Det er nå klart for å utvikle og skrive C# PowerShell modul i Visual Studio 2012.
 
Modulnavn og CmdLet
Navnet på modulen defineres av «namespace» og vil i «boble» eksemplet være BalloonNotification. Hver «CmdLet» opprettes som Class og [Cmdlet("Show", "Notification")] vil gi en CmdLet som får navnet «Show-Notification» under kjøring i PowerShell.

namespace BalloonNotification
{
    [Cmdlet("Show", "Notification")]
    public sealed class NotifyIconpop : PSCmdlet
    {
    }
}

 
Parametere til en CmdLet
For å opprettet parametere til en CmdLet anngir man egenskapene til parametere, for eksempel hvis parameteret er påkrevd (Mandatory). I eksemplet vil string IconType være pramameter nummer tre i rekkefølgen av aktuelle parametere for en CmdLet. I eksemplet er det også benyttet «ValidateSet» som angir de aktuelle valgene. Valgene vil komme som forslag ved bruk av «Tab» i PowerShell.

// Icon Type
[ValidateSet("Information", "Warning", "Error", "Exclamation", "Hand", "Shield", "Question")]
[Parameter(Mandatory = false, Position = 3)]
public string IconType
{
     get
     {
          return this.iconType;
     }
     set
     {
          this.iconType = value;
     }
}

Full kildekode modul BalloonNotification
Modulen BalloonNotification består av en CmdLet – Show-Notification. Show-Notification har fire parametre. Kildekoden beskriver også typisk bruk av klassen NotifyIcon og hendelseshåndtering ved bruk av «bobla».

Kildekode og kompilert modult kan lastes ned fra Technet Gallery: http://gallery.technet.microsoft.com/BalloonNotification-81c1cd0b

using System;
using System.Diagnostics;
using System.Management.Automation;
using System.Drawing;
using System.Windows.Forms;

namespace BalloonNotification
{
    [Cmdlet("Show", "Notification")]
    public sealed class NotifyIconpop : PSCmdlet
    {
        private string iconType;
        private string message;
        private string title;
        private string notifiaction;
        private System.Windows.Forms.NotifyIcon notify = new System.Windows.Forms.NotifyIcon();
                
        public ContextMenu contextMenu1 = new ContextMenu();
        public MenuItem menuItem1 = new System.Windows.Forms.MenuItem();

        // Message
        [ValidateNotNullOrEmpty]
        [Parameter(Mandatory = true, Position = 0)]
        public string Message
        {
            get
            {
                return this.message;
            }
            set
            {
                this.message = value;
            }
        }

        // Title
        [ValidateNotNullOrEmpty]
        [Parameter(Position = 1)]
        public string Title
        {
            get
            {
                return this.title;
            }
            set
            {
                this.title = value;
            }
        }

        // Action variable
        [ValidateNotNullOrEmpty]
        [Parameter(Mandatory = false, Position = 2)]
        public string NotifiAction
        {
            get
            {
                return this.notifiaction;
            }
            set
            {
                this.notifiaction = value;
            }
        }

        // Icon Type
        [ValidateSet("Information", "Warning", "Error", "Exclamation", "Hand", "Shield", "Question")]
        [Parameter(Mandatory = false, Position = 3)]
        public string IconType
        {
            get
            {
                return this.iconType;
            }
            set
            {
                this.iconType = value;
            }
        }
              
        // NotificationIcon Balloon start initilization 
        [STAThread]
        protected override void ProcessRecord()
        {
            base.ProcessRecord();
            Process thisProcess = Process.GetCurrentProcess();
         
            // Icon menu
            contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { menuItem1 });
            menuItem1.Index = 0;
            menuItem1.Text = "E&xit";
            menuItem1.Click += new System.EventHandler(menuItem1_Click);
          
            // Balloon and icon settings
            notify.Icon = typeof(SystemIcons).GetProperty(this.iconType).GetValue((object)null, (object[])null) as Icon;
            notify.BalloonTipIcon = ToolTipIcon.None;
            notify.BalloonTipText = this.Message;
            notify.BalloonTipTitle = this.Title;
            notify.ContextMenu = contextMenu1;
            notify.Visible = true
            notify.ShowBalloonTip(40);
            
            // If balloon clicked or closed
            notify.BalloonTipClicked += (sender, e) =>
            {
                // If no balloon action added
                if (string.IsNullOrEmpty(this.NotifiAction) == true)
                {
                    CleanUp(notify);
                }
                else
                {
                    System.Diagnostics.Process.Start(this.NotifiAction);
                    CleanUp(notify);
                }
            };
            notify.MouseMove += (sender, e) =>
            {
                notify.ShowBalloonTip(40);
                notify.Visible = true;
            };      
        }

        // Clean up
        static void CleanUp(System.Windows.Forms.NotifyIcon c)
        {
            c.Visible = false;
            c.Dispose();
            Application.Exit();
        }
        
        // Exit from menu
        private void menuItem1_Click(object Sender, EventArgs e)
        {
            CleanUp(notify);
        }          
    }
}

Bruk av modulen i PowerShell script


Eksempel på bruk av modulen i PowerShell script

Eksempel på bruk av modulen i PowerShell script


Dette eksemplet gir gjennom «bobla» informasjon om maskinen hvor scriptet kjører. Hvis man trykker på «bobla» opprettes en WEB-side hvor flere maskinegenskaper vises.

Import-Module BalloonNotification

#Region variabler
$WMIComputerSystem = get-wmiobject win32_computersystem -ComputerName $Env:COMPUTERNAME # WMI
$WMINetworks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Env:COMPUTERNAME | ? {$_.IPEnabled}
$UserNamedom = "$Env:USERDOMAIN" + "\" + "$Env:USERNAME" # USERNAME
$HtmFile = "C:\source\" + $Env:UserName + ".htm" # HTML FIL PATH

# MEMORY
If ($WMIComputerSystem.TotalPhysicalMemory -lt 1GB)
{        
	$Memory = "$('{00:N2}' -f ([MATH]::Round($WMIComputersystem.TotalPhysicalMemory / 1MB))) MB"    
}    
Else
{        
	$Memory = "$('{00:N2}' -f ([MATH]::Round($WMIComputersystem.TotalPhysicalMemory / 1GB))) GB"    
}

# IP
$IPAddress  = $WMINetworks.IPAddress[0]
# MAC
$MACAddress  = $WMINetworks.MACAddress
#EndRegion Variabler

#Region Maskin Objekter
$MaskinObj = New-Object -TypeName PSobject
$MaskinObj | Add-Member -MemberType NoteProperty -Name MaskinNavn -Value $Env:COMPUTERNAME # Maskinnavn
$MaskinObj | Add-Member -MemberType NoteProperty -Name Brukernavn -Value $UserNamedom # Brukernavn
$MaskinObj | Add-Member -MemberType NoteProperty -Name Modell -Value $WMIComputerSystem.Model
$MaskinObj | Add-Member -MemberType NoteProperty -Name Fabrikat -Value $WMIComputerSystem.Manufacturer # PC modell
$MaskinObj | Add-Member -MemberType NoteProperty -Name Minne -Value $Memory # Memory
$MaskinObj | Add-Member -MemberType NoteProperty -Name IP -Value $IPAddress # IP
$MaskinObj | Add-Member -MemberType NoteProperty -Name MAC -Value $MacAddress # MAC
#EndRegion Maskin Objekter		

#Region HTML
$a = "<style>"
$a = $a + "BODY{background-color:White;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:Grey}"
$a = $a + "TD{border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:DarkGrey}"
$a = $a + "</style>"

$data = 
$MaskinObj | Select-Object Maskinnavn, Brukernavn, Fabrikat, Modell, Minne, IP, MAC | 
ConvertTo-HTML -head $a -body "<H2>Maskininformasjon</H2>" | 
Out-File $HtmFile
#EndRegion HTML

#Notification message
$Message =  “Maskinnavn: $($MaskinObj.Maskinnavn) `nBrukernavn: $($MaskinObj.brukernavn) `n`nFabrikat: $($MaskinObj.Fabrikat) `nModell: $($MaskinObj.modell) `nIP-addresse: $($MaskinObj.ip) `nMAC-address: $($MaskinObj.IP)”
Show-Notification -Message $Message -Title "Information" -NotifiAction $HtmFile -IconType Information

Post to Twitter Post to Facebook Post to LinkedIn

Panorama Theme by Themocracy