enum VERB { kPinToTaskbarID = 5386, // Win7+ kUnpinFromTaskbarID = 5387, // Win7+ kPinToStartID = 51201, // Win8+ kUnpinFromStartID = 51394 // Win10+ }; bool DoVerbOnFile(VERB verb, LPCWSTR path, LPCWSTR file) { if (path == NULL || !PathFileExists(path)) return true; WCHAR filepath[MAX_PATH] = { 0, }; if (file == NULL) { lstrcpy(filepath, path); wchar_t *p = wcsrchr(filepath, L'\\'); if (p) { *p = '\0'; file = p + 1; path = filepath; } } const wchar_t* resource_ptr = NULL; int length = ::LoadStringW(LoadLibrary(L"shell32.dll"), (DWORD)verb, reinterpret_cast<wchar_t*>(&resource_ptr), 0); if (length == 0 || resource_ptr == NULL) return false; std::wstring ResName(resource_ptr, length); CComPtr<IShellWindows> ShellWindow; HRESULT hr = ShellWindow.CoCreateInstance(CLSID_ShellWindows); if (FAILED(hr)) return false; CComVariant varloc(0); CComVariant varlocroot(0); CComPtr<IDispatch> pdisp; long lHwnd = 0; int nOptions = SWFO_NEEDDISPATCH; hr = ShellWindow->FindWindowSW(&varloc, &varlocroot, 8, &lHwnd, nOptions, &pdisp); if (FAILED(hr)) return false; CComPtr<IWebBrowserApp> BrowserApp; hr = pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&BrowserApp); if (FAILED(hr)) return false; CComPtr<IServiceProvider> ServiceProvider; hr = BrowserApp->QueryInterface(IID_IServiceProvider, (void**)&ServiceProvider); if (FAILED(hr)) return false; CComPtr<IShellBrowser> ShellBrowser; hr = ServiceProvider->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&ShellBrowser); if (FAILED(hr)) return false; CComPtr<IShellView> ShellView; hr = ShellBrowser->QueryActiveShellView(&ShellView); if (FAILED(hr)) return false; pdisp.Release(); hr = ShellView->GetItemObject(0, IID_IDispatch, (LPVOID*)&pdisp); if (FAILED(hr)) return false; CComPtr<IShellFolderViewDual> ShellFolderView; hr = pdisp->QueryInterface(IID_IShellFolderViewDual, (LPVOID*)&ShellFolderView); if (FAILED(hr)) return false; pdisp.Release(); hr = ShellFolderView->get_Application(&pdisp); if (FAILED(hr)) return false; CComPtr<IShellDispatch2> ShellDispatch; hr = pdisp->QueryInterface(IID_IShellDispatch2, (LPVOID*)&ShellDispatch); if (FAILED(hr)) return false; CComPtr<Folder> fo; hr = ShellDispatch->NameSpace(CComVariant(path), &fo); if (FAILED(hr)) return false; CComPtr<FolderItem> fot; hr = fo->ParseName(CComBSTR(file), &fot); if (FAILED(hr)) return false; CComPtr<FolderItemVerbs> fotv; hr = fot->Verbs(&fotv); if (FAILED(hr)) return false; long cnt; hr = fotv->get_Count(&cnt); if (FAILED(hr)) return false; int i = 0; for (; i < cnt; ++i) { CComPtr<FolderItemVerb> foiv; if (FAILED(fotv->Item(CComVariant(i), &foiv))) continue;; CComBSTR VerbName; if (FAILED(foiv->get_Name(&VerbName))) continue;; if (ResName == (LPCWSTR)VerbName) { foiv->DoIt(); break; } } return SUCCEEDED(hr) && i < cnt; } bool TaskbarAndStartPin(bool bPin, LPCWSTR filepath) { CoInitialize(NULL); if (!DoVerbOnFile(bPin ? VERB::kPinToTaskbarID : VERB::kUnpinFromTaskbarID, filepath)) return false; return DoVerbOnFile(bPin ? VERB::kPinToStartID : VERB::kUnpinFromStartID, filepath); }
這個代碼能夠有效的將文件和目錄固定要任務欄與開始菜單, 有部分是摘自Chromium源碼, 可是Chromium中的實現方式不能有效的工做在Win10上.shell
原理很少說了, 一切都在代碼中。ide