Refreshing the Notification Area (System Tray)

Because I am forcibly killing certain processes regularly, I end up with orphaned icons in what is apparently called the Notification Area, not the System Tray.

I found a good StackOverflow answer, but it needed some updates:
Can you send a signal to Windows Explorer to make it refresh the systray icons?

The answer draws its information from this informative post:
REFRESHING THE TASKBAR NOTIFICATION AREA

But the information is from 2008.  The name of the window used in XP has changed in Windows 7 (actually probably in Vista).  In addition to this, the code only works on visible icons, not on those that are currently hiding.  The following code is updated to clear both visible and hidden icons.

 

//WinXP
    GetClientRect(
        hNotificationArea = FindWindowEx(
            FW(FW(FW(NULL, L"Shell_TrayWnd"), L"TrayNotifyWnd"), L"SysPager"),
            NULL,
            L"ToolbarWindow32",
            L"Notification Area"),
        &r);

    for (LONG x = 0; x < r.right; x += 5)
        for (LONG y = 0; y < r.bottom; y += 5)
            SendMessage(
                hNotificationArea,
                WM_MOUSEMOVE,
                0,
                (y << 16) + x);

	//Visible icons
    GetClientRect(
        hNotificationArea = FindWindowEx(
            FW(FW(FW(NULL, L"Shell_TrayWnd"), L"TrayNotifyWnd"), L"SysPager"),
            NULL,
            L"ToolbarWindow32",
            L"User Promoted Notification Area"),
        &r);

    for (LONG x = 0; x < r.right; x += 5)
        for (LONG y = 0; y < r.bottom; y += 5)
            SendMessage(
                hNotificationArea,
                WM_MOUSEMOVE,
                0,
                (y << 16) + x);

	//Hidden icons
	GetClientRect(
        hNotificationArea = FindWindowEx(
            FW(NULL, L"NotifyIconOverflowWindow"),
            NULL,
            L"ToolbarWindow32",
            L"Overflow Notification Area"),
        &r);

    for (LONG x = 0; x < r.right; x += 5)
        for (LONG y = 0; y < r.bottom; y += 5)
            SendMessage(
                hNotificationArea,
                WM_MOUSEMOVE,
                0,
                (y << 16) + x);

Utility available here: Refresh Notification Area

By the way, if you have the opposite problem as me and are losing the icons of programs still running, see the following:
Can I re-gain a systray icon of a running app that has gone missing?
trayrestore

 

I’ve posted my updates to the StackOverflow answer: http://stackoverflow.com/a/18038441/221018

Current Directory in Elevated Batch Scripts in Windows 8

I am seeing a difference between elevated batch scripts in Windows 7 and Windows 8.  If you copy the following in the a batch script and run in either version, you get the current directory.  However if you right-click Run As Administrator, you see the current directory in Windows 7 and “C:Windowssystem32” in Windows 8:

@echo off
echo Current path is %cd
%pause

Fortunately there is an easy workaround by changing the current directory to the path of the current script (parameter zero):

@echo off
echo Current path is %cd%
echo Changing directory to the path of the current script
cd %~dp0
echo Current path is %cd%
pause

I’m using this in context of the StackOverflow answer showing how to auto elevate a script:
How can I auto-elevate my batch file, so that it requests from UAC admin rights if required?

I added this info in case anyone else had the same issue: http://stackoverflow.com/a/18037959/221018