locked
Using Icons in Powershell Scripts RRS feed

  • Question

  • Hi there.

    I am creating a powershell script that will execute a long job and I am referencing the "System.Windows.Forms.NotifyIcon" to show in the task tray when the script has finished. The issue I'm having is using the "System.Windows.Forms.NotifyIcon.Icon" property to reference an icon file. Now with this script being portable I would like to know if it is possible to reference an icon within a .DLL or .EXE instead of having to extract and copy the icon file with the script. I was hoping to use the icons within Shell32.DLL. I would think this is possible since other built-in Windows applications are capable of doing this e.g. Explorer.exe. Any ideas as I cant seem to find an answer on the web.


    • Edited by TheGuyFromIT Monday, August 15, 2011 11:15 AM spelling errors
    Monday, August 15, 2011 11:14 AM

Answers

  • $code = @"
    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;
    
    namespace System
    {
    	public class IconExtractor
    	{
    
    	 public static Icon Extract(string file, int number, bool largeIcon)
    	 {
    	  IntPtr large;
    	  IntPtr small;
    	  ExtractIconEx(file, number, out large, out small, 1);
    	  try
    	  {
    	   return Icon.FromHandle(largeIcon ? large : small);
    	  }
    	  catch
    	  {
    	   return null;
    	  }
    
    	 }
    	 [DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    	 private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);
    
    	}
    }
    "@
    
    Add-Type -TypeDefinition $code -ReferencedAssemblies System.Drawing
    
    $form = New-Object System.Windows.Forms.Form
    $form.Icon = [System.IconExtractor]::Extract("shell32.dll", 42, $true)
    $form.ShowDialog()
    

     

    http://stackoverflow.com/questions/6872957/how-can-i-use-the-images-within-shell32-dll-in-my-c-project

    • Proposed as answer by Rich Prescott Monday, August 15, 2011 1:07 PM
    • Marked as answer by TheGuyFromIT Tuesday, August 16, 2011 11:19 AM
    Monday, August 15, 2011 11:33 AM
  • You can extract the icon with Drawing.Icon's ExtractAssociatedIcon Static Method, it takes the path to the file. Need to add the Drawing assembly. The sample code extracts the PowerShell icon and sets it to the balloon tip:

    Add-Type -AssemblyName System.Drawing

    $NotifyIcon.Icon = [Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path)

     


      Robert Robelo  
    • Marked as answer by TheGuyFromIT Tuesday, August 16, 2011 11:19 AM
    Monday, August 15, 2011 6:34 PM

All replies

  • $code = @"
    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;
    
    namespace System
    {
    	public class IconExtractor
    	{
    
    	 public static Icon Extract(string file, int number, bool largeIcon)
    	 {
    	  IntPtr large;
    	  IntPtr small;
    	  ExtractIconEx(file, number, out large, out small, 1);
    	  try
    	  {
    	   return Icon.FromHandle(largeIcon ? large : small);
    	  }
    	  catch
    	  {
    	   return null;
    	  }
    
    	 }
    	 [DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    	 private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);
    
    	}
    }
    "@
    
    Add-Type -TypeDefinition $code -ReferencedAssemblies System.Drawing
    
    $form = New-Object System.Windows.Forms.Form
    $form.Icon = [System.IconExtractor]::Extract("shell32.dll", 42, $true)
    $form.ShowDialog()
    

     

    http://stackoverflow.com/questions/6872957/how-can-i-use-the-images-within-shell32-dll-in-my-c-project

    • Proposed as answer by Rich Prescott Monday, August 15, 2011 1:07 PM
    • Marked as answer by TheGuyFromIT Tuesday, August 16, 2011 11:19 AM
    Monday, August 15, 2011 11:33 AM
  • You can extract the icon with Drawing.Icon's ExtractAssociatedIcon Static Method, it takes the path to the file. Need to add the Drawing assembly. The sample code extracts the PowerShell icon and sets it to the balloon tip:

    Add-Type -AssemblyName System.Drawing

    $NotifyIcon.Icon = [Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path)

     


      Robert Robelo  
    • Marked as answer by TheGuyFromIT Tuesday, August 16, 2011 11:19 AM
    Monday, August 15, 2011 6:34 PM
  • Thank you Kazun and Robert. Both solutions worked for my purpose.
    Tuesday, August 16, 2011 11:22 AM