Windows 7 Taskbar: Check if a program or window is pinned





4.00/5 (1 vote)
Example code to check if a program or window is pinned on the Windows 7 taskbar.
Introduction
The new taskbar in Windows 7 provides a feature to 'pin' programs to the taskbar. Pinned taskbar buttons will be visible in the taskbar even if the program is not running. This article provides functions to check if a program or window is pinned or not.
Background
I use this code for a virtual desktop manager. If a program is pinned, I do not need to show/hide the taskbar buttons during desktop change.
How it works
All currently pinned programs have a symbolic link in the folder C:\Users\Username\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar. My solution to check if a program is pinned or not is to look if one of the symbolic links is pointing to the program's executable:
- get the first symbolic link from the '..\TaskBar' folder
- retrieve the path to the exe the symbolic link is pointing to
- compare the path with the path I am looking for, if equal: stop and return true
- if not: get the next symbolic link
I put the code in a class. The class provide these two static methods:
static result TaskbarPinUtility::checkIfWindowIsPinned(HWND window);
static result TaskbarPinUtility::checkIfProgramIsPinned(std::wstring& pathISearch);
TaskbarPinUtility::checkIfWindowIsPinned()
gets the path to the executable of the window with the function getWindowFileName()
(look in the example code for the implementation) and then calls TaskbarPinUtility::checkIfProgramIsPinned()
:
//check if the executable of a window ID is pinned
result TaskbarPinUtility::checkIfWindowIsPinned(HWND window)
{
result res=no;
if (!IsWindow(window))
{
return error;
}
//path to the executable of the window
wstring *pathToExe=getWindowFileName(window);
if (pathToExe==NULL)
{
return error;
}
//use this path to search for a link...
res=checkIfProgramIsPinned(*pathToExe);
delete pathToExe;
return res;
}
TaskbarPinUtility::checkIfProgramIsPinned()
loops through all links in the ..\TaskBar folder until a symbolic link is pointing to pathISearch
:
result TaskbarPinUtility::checkIfProgramIsPinned(wstring& pathISearch)
{
WIN32_FIND_DATAW ffd;
HANDLE hFind = INVALID_HANDLE_VALUE;
result res=no;
PWSTR quickLaunchPath;
//get the quick launch folder:
//C:\Users\pulp\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch
if (SHGetKnownFolderPath(FOLDERID_QuickLaunch, 0, NULL, &quickLaunchPath)== S_OK)
{
//append '\User Pinned\TaskBar\*.lnk'
wstring quickLaunchPathEx(quickLaunchPath);
quickLaunchPathEx.append(L"\\User Pinned\\TaskBar\\*.lnk");
//get all symbolic links in the directory until
//a link is pointing to 'pathISearch'
hFind = FindFirstFileW(quickLaunchPathEx.c_str(), &ffd);
if (hFind!=INVALID_HANDLE_VALUE)
{
do
{
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
//create a string with the complete path to the link
wstring linkPath(quickLaunchPath);
linkPath.append(L"/User Pinned/TaskBar/").append(ffd.cFileName);
//get the path the link is pointing to
wstring *linkTarget=getPathLinkIsPointingTo(linkPath);
if (linkTarget!=NULL)
{
//if the returned path is the same as 'pathISearch', leave the loop
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE,
pathISearch.c_str(), -1, linkTarget->c_str(), -1)==CSTR_EQUAL)
{
res=yes;
}
delete linkTarget;
if (res==yes)
{
break;
}
}
}
}
while (FindNextFileW(hFind, &ffd) != 0);
FindClose(hFind);
}
CoTaskMemFree(quickLaunchPath);
}
return res;
}
The path to the executable the symbolic link is pointing to is resolved with the use of IShellLink:
:
//get the path the symbolic link is pointing to, using IShellLink
wstring *TaskbarPinUtility::getPathLinkIsPointingTo(wstring& lpszLinkFile)
{
IShellLinkW* psl;
wstring *path=NULL;
if (CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLinkW, (LPVOID*)&psl)==S_OK)
{
IPersistFile* ppf;
if (psl->QueryInterface(IID_IPersistFile, (void**)&ppf)==S_OK)
{
if (ppf->Load(lpszLinkFile.c_str(), STGM_READ)==S_OK)
{
if(psl->Resolve(NULL, 0)==S_OK)
{
WCHAR szGotPath[MAX_PATH];
if (psl->GetPath(szGotPath, MAX_PATH, NULL, SLGP_UNCPRIORITY)==S_OK)
{
path= new wstring(szGotPath);
}
}
}
ppf->Release();
}
psl->Release();
}
return path;
}
An example project (32 and 64 bit) for Visual Studio 2008 is provided as download.
History
- 15 Nov., 2009: Initial post.