Win 10 固定程序到任務欄開始菜單的代碼

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

相關文章
相關標籤/搜索