Click here to Skip to main content
Click here to Skip to main content

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

, 15 Nov 2009 CPOL
Rate this:
Please Sign up or sign in to 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:

  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:

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.

License

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

Share

About the Author

Jochen Baier

Germany Germany
No Biography provided

Comments and Discussions

 
QuestionIs there the vb.net or C# version? Pinmemberstevenyoung15-Nov-09 13:46 
AnswerRe: Is there the vb.net or C# version? PinmemberJochen Baier16-Nov-09 0:15 
GeneralRe: Is there the vb.net or C# version? Pinmemberstevenyoung16-Nov-09 1:35 
Thank you for your reply, can the code pin a program with known applicaton ID to taskbar?
GeneralRe: Is there the vb.net or C# version? PinmemberJochen Baier16-Nov-09 2:58 
GeneralRe: Is there the vb.net or C# version? Pinmemberstevenyoung16-Nov-09 4:33 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 15 Nov 2009
Article Copyright 2009 by Jochen Baier
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid