Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / Win32

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

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
15 Nov 2009CPOL1 min read 38.7K   456   21   5
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:

  1. get the first symbolic link from the '..\TaskBar' folder
  2. retrieve the path to the exe the symbolic link is pointing to
  3. compare the path with the path I am looking for, if equal: stop and return true
  4. if not: get the next symbolic link

I put the code in a class. The class provide these two static methods:

C++
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():

C++
//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:

C++
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::

C++
//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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionIs there the vb.net or C# version? Pin
stevenyoung15-Nov-09 12:46
stevenyoung15-Nov-09 12:46 
AnswerRe: Is there the vb.net or C# version? Pin
Jochen Baier15-Nov-09 23:15
Jochen Baier15-Nov-09 23:15 
GeneralRe: Is there the vb.net or C# version? Pin
stevenyoung16-Nov-09 0:35
stevenyoung16-Nov-09 0:35 
GeneralRe: Is there the vb.net or C# version? Pin
Jochen Baier16-Nov-09 1:58
Jochen Baier16-Nov-09 1:58 
GeneralRe: Is there the vb.net or C# version? Pin
stevenyoung16-Nov-09 3:33
stevenyoung16-Nov-09 3:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.