删除任务栏锁定,任务栏图标的位置,查找可行性文件的方式

原创 2015年07月09日 10:16:17

这几天改bug,遇到一个删除任务栏快捷图标的问题。本来想着应该挺简单的,估计是在注册表或者C盘的某个位置放置着一个链接,一删除就可以搞定。没想到没那么简单。

C:\Users\LeoLi\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar这个目录下放的就是任务栏中的快捷方式。我之前以为只要把这个地方的lnk删除了,就相当于去掉了任务栏快捷图标,但是结果还是存在,只是你点击的时候系统提示该链接已失效。看来这个方法是行不通的。

网上去搜资料,发现有篇介绍任务栏列表的文章:http://www.codeproject.com/Articles/36561/Windows-Goodies-in-C-Jump-Lists。这篇文章不是介绍如何删除任务栏锁定,而且介绍了为什么我们在任务栏的图标上右键的时候,会看到很多额外的信息,都是程序自己加上去的。所以可以适当的了解下。然后其实了解了这块内容,删除任务栏锁定就不是什么难题了。代码如下:

bool UnLockWinTaskBarLink( const String runPath )
{
    HINSTANCE hModule = ::LoadLibrary(_T("Shell32.dll")) ;
    if (hModule == NULL)
    {
        return false ;
    }
    typedef HRESULT (__stdcall* SHCreateItemFromParsingName)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv) ;
    SHCreateItemFromParsingName mySHCreateItemFromParsingName = (SHCreateItemFromParsingName)GetProcAddress(hModule, "SHCreateItemFr        omParsingName") ;
    if (mySHCreateItemFromParsingName == NULL)
    {
        return false ;
    }
    bool result = true ;
    do
    {
        CComPtr<IShellItem> spItem ;
        HRESULT hr = mySHCreateItemFromParsingName(
        runPath.c_str(), NULL, IID_PPV_ARGS(&spItem)) ;
        if (FAILED(hr))
        {
            result = false ;
            break ;
        }
        CComPtr<IStartMenuPinnedList> spStartMenuPinnedList ;
        hr = CoCreateInstance(CLSID_StartMenuPin, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&spStartMenuPinnedList)) ;
        if (FAILED(hr))
        {
            result = false ;
            break ;
        }
        hr = spStartMenuPinnedList->RemoveFromList(spItem) ;
        if (FAILED(hr))
        {
            result = false ;
        }
    } while (false) ;
    FreeLibrary(hModule) ;
    return result;
}
代码的逻辑应该是不用多说,就是利用Shell32.dll的导出函数SHCreateItemFromParsingName,系统对每个任务栏锁定都相应的记录,通过这个程序的可执行文件的位置,我们可以得到一个操作这个程序的“标识”,便于去删除。

其实我多次看到Shell.dll的调用,这是一个很有用的dll,提供了很多操作系统的方法,我网上找了下这方面的总结,比较少,等以后用的多的再继续更新。

现在的问题似乎解决了,但是不要忘记,这个函数需要一个参数,也就是被删除任务栏锁定的可执行文件的位置。这儿可能很多人都说,直接获取当前路径不就完了吗?有现成的API。但问题是,如果要你删除的不是你自己的程序呢,随便给一个程序,让你解除任务栏绑定,你怎么去找到这个程序的exe的位置呢?

我之前的思路是系统肯定知道所有exe的位置,那注册表里有记录,可以直接找了半天没什么收获(其实确实有的,稍后说)。那最直接的办法就是全盘搜索,耗时巨大。一般来说程序的安装目录不会有太多层,我们遍历个7,8层应该都是可以检索出来的。而且还可以优先遍历某几个很有可能的文件夹,这样的设计显然不好。于是就想了个歪点子,我们能找到快捷链接的位置,右击快捷方式不是可以看到目标位置吗?那有没有办法获取到快捷方式的信息呢?答案是:有的。代码如下:

BOOL GetIEQuickLaunchPath(TCHAR *pszIEQueickLaunchPath)
{
    LPITEMIDLIST ppidl;
    if (SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &ppidl) == S_OK)
    {
        BOOL flag = SHGetPathFromIDList(ppidl, pszIEQueickLaunchPath);
        ::wcscat_s(pszIEQueickLaunchPath, MAX_PATH, _T("\\Microsoft\\Internet Explorer\\Quick Launch"));
        CoTaskMemFree(ppidl);
        return flag;
    }
    return FALSE;
}

bool SearchExePathByLnk(String StrTargetFile, WCHAR* szDesEXEPath)
{
    ::CoInitialize(NULL); //初始化COM接口  
    IShellLink *psl = NULL;

    HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl);
    if (SUCCEEDED(hr))
    {
        IPersistFile *ppf;
        hr = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
        if (SUCCEEDED(hr))
        {
            hr = ppf->Load(StrTargetFile.c_str(), STGM_READ);    //加载文件  
            if (SUCCEEDED(hr))
            {
                WIN32_FIND_DATA wfd;
                psl->GetPath(szDesEXEPath, MAX_PATH, (WIN32_FIND_DATA*)&wfd, SLGP_SHORTPATH);  //获取目标路径  
                return true;
            }
            ppf->Release();
        }
        psl->Release();  //释放对象  
    }
    ::CoUninitialize();   //释放COM接口  

    return false;
}


    String StrTargetFile;
    PIDLIST_ABSOLUTE pid;
    TCHAR szDocument[MAX_PATH + 1] = { 0 };
    WCHAR szDesEXEPath[MAX_PATH] = L"";

    GetIEQuickLaunchPath(szDocument);
    StrTargetFile.append(szDocument);
    StrTargetFile.append(_T("\\User Pinned\\TaskBar\\"));
    StrTargetFile.append(_T("酷我音乐.lnk"));
   
    SearchExePathByLnk(StrTargetFile, szDesEXEPath);
    UnLockWinTaskBarLink(RCString(szDesEXEPath));
    DeleteFile(StrTargetFile.c_str());

上面的代码中,通过lnk查找可执行文件的位置是参考的是另一位博友的博客:点击打开链接 http://blog.csdn.net/yoie01/article/details/8688686 。只要任务栏有锁定,那么%AppData%Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar中就一定有这个快捷方式,那这样的话,问题就解决了。

当然这不是什么好方法,后来我找到了注册表里关于信息的记录。在一个项名为Uninstall的下面,这个项有两个地方,不固定某一个,所以需要都检索一下,具体位置是:

HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall  ;

HKEY_LOCAL_MACHINE, _T("Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall  。

找到这个地方,剩下的就是读取注册表了,这个应该就非常简单了吧?

删除任务栏锁定,任务栏图标的位置,查找可行性文件的方式

http://blog.csdn.net/yoie01/article/details/8688686
  • yongshi6
  • yongshi6
  • 2015年07月09日 10:16
  • 1431

任务栏中的工具栏自定义一个搜索框

  • 2011年08月14日 18:59
  • 58KB
  • 下载

VS下Qt应用程序图标和任务栏图标设置

Qt应用程序图标设置 Qt任务栏图标设置 注意应用程序图标和任务栏图标是不同的东西不要混淆1.Qt应用程序图标设置 添加资源文件 在vs资源视图中选中项目右键->添加->资源,选择icon或者ver...
  • u013295518
  • u013295518
  • 2017年12月26日 18:47
  • 26

Qt任务栏,托盘栏,托盘菜单,图标等操作

隐藏任务栏 setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint|Qt::Tool);//不显示任务栏图标 ...
  • yh_1988
  • yh_1988
  • 2016年05月25日 17:15
  • 1753

查找指定进程

DWORD SystemInfo::findProcess(char* strProcessName) { DWORD aProcesses[1024]={0}; DWORD cbNeede...
  • ckkyjtqlt
  • ckkyjtqlt
  • 2017年04月21日 11:15
  • 79

xp系统 任务栏 “搜索桌面” 如何去掉

针对XP系统,有时候在某些系统更新后, 任务栏右下角出现 搜索桌面的InputBox,去掉方式: 右击任务栏 -- 工具栏 -- Windows Search 桌面工具栏 (勾掉)。...
  • leslietuang
  • leslietuang
  • 2013年12月21日 16:26
  • 1810

MFC 子窗口任务栏显示图标和主窗口最小化在系统托盘中显示图标

MFC子窗口任务栏显示图标很简单, 只需要在子窗口的初期化函数OnInitDialog()中添加ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW); ...
  • dragonrxl
  • dragonrxl
  • 2012年10月30日 16:40
  • 3308

MFC程序隐藏任务栏图标的三种方法

在VC编程中,有时候我们需要将我们的程序在任务栏上的显示隐藏起来,我试过几种方法,下面我介绍一下我知道的三种方法。   第一种方法是设置窗口WS_EX_TOOLWINDOW扩展样式,通过在OnI...
  • lonelyrains
  • lonelyrains
  • 2014年10月17日 23:40
  • 4435

电脑文件搜索神器

  • 2012年05月04日 13:48
  • 1.27MB
  • 下载

vc 找到窗口之后并关闭,运行时最小化的实现方法

  • 2009年04月01日 16:38
  • 26KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:删除任务栏锁定,任务栏图标的位置,查找可行性文件的方式
举报原因:
原因补充:

(最多只允许输入30个字)