Make a Window Flash in Taskbar using PowerShell and PInvoke

While working on a different project, I came across the need to do some sort of notification when something happened during a script. I didn’t need popup or some loud noise to alert me, but something a little subtle to look over and see when an action had occurred.

After some thinking, I decided on making the icon in the taskbar flash when something happened. The trick is that this isn’t something easily done just by itself with PowerShell. I had to go deeper down the rabbit hole into the realm of pinvoke to make something like this happen.

Looking at pinvoke.net, I came across 2 possible solutions to my dilemma:

In the end, I chose FlashWindowEx and the reason for this is that while FlashWindow has the easiest approach to setup and use…

image

…it doesn’t allow the capability to control the flash rate and set number of flashes that can occur before showing a solid pane of the flashing color (usually orange).

With FlashWindowEx, there are more pieces to put together before it will function properly.

image

We have a Struct and some defined constants that handle how the flashing will occur with the window. Before I get started, you can take a look at some of my previous articles that talk about using pinvoke with PowerShell so you can see what has been done in the past.

As I have done in the past, I put the signature into a here-string that will be used with Add-Type to compile the code and make it available to my current session.

Add-Type -TypeDefinition @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

public class Window
{
    [StructLayout(LayoutKind.Sequential)]
    public struct FLASHWINFO
    {
        public UInt32 cbSize;
        public IntPtr hwnd;
        public UInt32 dwFlags;
        public UInt32 uCount;
        public UInt32 dwTimeout;
    }

    //Stop flashing. The system restores the window to its original state. 
    const UInt32 FLASHW_STOP = 0;
    //Flash the window caption. 
    const UInt32 FLASHW_CAPTION = 1;
    //Flash the taskbar button. 
    const UInt32 FLASHW_TRAY = 2;
    //Flash both the window caption and taskbar button.
    //This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags. 
    const UInt32 FLASHW_ALL = 3;
    //Flash continuously, until the FLASHW_STOP flag is set. 
    const UInt32 FLASHW_TIMER = 4;
    //Flash continuously until the window comes to the foreground. 
    const UInt32 FLASHW_TIMERNOFG = 12; 


    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool FlashWindowEx(ref FLASHWINFO pwfi);

    public static bool FlashWindow(IntPtr handle, UInt32 timeout, UInt32 count)
    {
        IntPtr hWnd = handle;
        FLASHWINFO fInfo = new FLASHWINFO();

        fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo));
        fInfo.hwnd = hWnd;
        fInfo.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG;
        fInfo.uCount = count;
        fInfo.dwTimeout = timeout;

        return FlashWindowEx(ref fInfo);
    }
}
"@

Now I have my compiled code ready to use!

image

The next step is to get the MainWindowHandle of a window that is either minimized or not currently active. In this case, I will use something like notepad as the example.

$handle = (Get-Process -Name Notepad).MainWindowHandle
$handle

image

Now to make the window flash. In this case, I am going to make it flash every 150 milliseconds and only flash 10 times.

[window]::FlashWindow($handle,150,10)

image

Now I have a flashing window!

image

Note:This will only work if the window is not currently in focus! It must either be minimized or the focus shifted to some other window.

All I have to do now is to click on the taskbar icon and bring the window up to the front and it will stop flashing or go back to its original state.

Sounds like a good candidate for a function, right? Well, you are right! I went ahead and put a function together called Invoke-FlashWindow which makes the process of having a window flash easier.

image

The following parameters are being used.

  1. MainWindowHandle
    1. Handle of the window that will be set to flash
  2. FlashRate
    1. The rate at which the window is to be flashed, in milliseconds. Default value is: 0 (Default cursor blink rate)
  3. FlashCount
    1. The number of times to flash the window. Default value is: 2147483647

One example is by using the current PowerShell console and put the console to sleep for a few seconds (enough time to either minimize or shift the focus to something else) and then make the window flash. The use of semicolon is by design.

Start-Sleep -Seconds 5; Get-Process -Id $PID | Invoke-FlashWindow

image

 

Hopefully you will find some other uses for this script in your environment. You can download the script from the link below.

Download

Technet Script Repository

About Boe Prox

Microsoft Cloud and Datacenter MVP working as a SQL DBA.
This entry was posted in powershell, scripts and tagged , , , , . Bookmark the permalink.

One Response to Make a Window Flash in Taskbar using PowerShell and PInvoke

  1. m sorens says:

    Very handy cmdlet–thanks for the work putting this together, Boe!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s