以前写过一些脚本调用 Shell Object 实现的解锁和锁定程序到任务栏的功能,这几天刚好用到,却不想用脚本实现,由于没有了解过 VC 如何操作 Shell,所以就在 github 上搜索了一下,找到了示例代码,自己修改了一下以后备用。代码有使用方法和注释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// TaskbarShortcut.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <shlobj.h>

/************************************************************************/
/*
/* 代码来源:https://github.com/prestocore/browser/blob/8c5977d18f4ed8aea10547829127d52bc612a725/platforms/windows/WindowsShortcut.cpp
/* 函数功能:将程序锁定或从任务栏解锁
/* 函数参数:
/* lpPath:要锁定或解锁文件的路径
/* lpFileName:要锁定或解锁文件的文件名
/* bIsPin:TRUE 为锁定文件到任务栏,FALSE 为从任务栏解锁,默认为 FALSE
/*
/************************************************************************/

BOOL TaskbarPin(LPTSTR lpPath, LPTSTR lpFileName, BOOL bIsPin = FALSE)
{
BOOL bRet = FALSE;
HMENU hmenu = NULL;
LPSHELLFOLDER pdf = NULL;
LPSHELLFOLDER psf = NULL;
LPITEMIDLIST pidl = NULL;
LPITEMIDLIST pitm = NULL;
LPCONTEXTMENU pcm = NULL;

if (SUCCEEDED(SHGetDesktopFolder(&pdf))
&& SUCCEEDED(pdf->ParseDisplayName(NULL, NULL, lpPath, NULL, &pidl, NULL))
&& SUCCEEDED(pdf->BindToObject(pidl, NULL, IID_IShellFolder, (void **)&psf))
&& SUCCEEDED(psf->ParseDisplayName(NULL, NULL, lpFileName, NULL, &pitm, NULL))
&& SUCCEEDED(psf->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST *)&pitm, IID_IContextMenu, NULL, (void **)&pcm))
&& (hmenu = CreatePopupMenu()) != NULL
&& SUCCEEDED(pcm->QueryContextMenu(hmenu, 0, 1, INT_MAX, CMF_NORMAL)))
{
CMINVOKECOMMANDINFO ici = { sizeof(CMINVOKECOMMANDINFO), 0 };
ici.hwnd = NULL;
ici.lpVerb = bIsPin ? "taskbarpin" : "taskbarunpin";
pcm->InvokeCommand(&ici);
bRet = TRUE;
}

if (hmenu)
DestroyMenu(hmenu);
if (pcm)
pcm->Release();
if (pitm)
CoTaskMemFree(pitm);
if (psf)
psf->Release();
if (pidl)
CoTaskMemFree(pidl);
if (pdf)
pdf->Release();

return bRet;
}

int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(nullptr);

// 将 Win7 默认的 Media Player 快捷方式从任务栏取消固定
TaskbarPin(
_T("C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs"),
_T("Windows Media Player.lnk")
);

// 将 Win7 默认的 IE 快捷方式从任务栏取消固定
TaskbarPin(
_T("C:\\Users\\Administrator\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs"),
_T("Internet Explorer.lnk")
);

CoUninitialize();
return 0;
}