Get path to all users' start menu on Windows

三世轮回 提交于 2019-12-12 03:17:48

问题


I am looking for a way to retrieve the path to the all users start menu directory in C++. I am only able to get the one of the current user (using Qt):

QString startMenuPath = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).at(0);

However, Qt does not allow to retrieve the one for all users. As far as I know there also is no environment variable containing that path, that I could read.


回答1:


To get a known folder, use SHGetFolderPath, and pass a KNOWNFOLDERID or CSIDL for the desired folder.

For example, the following code gets the All Users Start Menu and the Programs folder:

// Remember to #include <Shlobj.h>

WCHAR path[MAX_PATH];

HRESULT hr = SHGetFolderPathW(NULL, CSIDL_COMMON_PROGRAMS, NULL, 0, path);
if (SUCCEEDED(hr))
    std::wcout << L"Start Menu\Programs: " << path << std::endl;

hr = SHGetFolderPathW(NULL, CSIDL_COMMON_STARTMENU, NULL, 0, path);
if (SUCCEEDED(hr))
    std::wcout << L"Start Menu: " << path << std::endl;



回答2:


Thanks goes to user theB for the solution. Here my final piece of code for creating a shortcut in the all-users start menu on Windows (uses Qt):

#include <shlobj.h>

bool createStartMenuEntry(QString targetPath) {
    targetPath = QDir::toNativeSeparators(targetPath);

    WCHAR startMenuPath[MAX_PATH];
    HRESULT result = SHGetFolderPathW(NULL, CSIDL_COMMON_PROGRAMS, NULL, 0, startMenuPath);

    if (SUCCEEDED(result)) {
        QString linkPath = QDir(QString::fromWCharArray(startMenuPath)).absoluteFilePath("Some Link.lnk");

        CoInitialize(NULL);
        IShellLinkW* shellLink = NULL;
        result = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkW, (void**)&shellLink);
        if (SUCCEEDED(result)) {
            shellLink->SetPath(reinterpret_cast<LPCWSTR>(targetPath.utf16()));
            shellLink->SetDescription(L"Description");
            shellLink->SetIconLocation(reinterpret_cast<LPCWSTR>(targetPath.utf16()), 0);

            IPersistFile* persistFile;
            result = shellLink->QueryInterface(IID_IPersistFile, (void**)&persistFile);

            if (SUCCEEDED(result)) {
                result = persistFile->Save(reinterpret_cast<LPCOLESTR>(linkPath.utf16()), TRUE);

                persistFile->Release();
            } else {
                return false;
            }
            shellLink->Release();
        } else {
            return false;
        }
    } else {
        return false;
    }
    return true;
}



回答3:


The path to any user's start menu is going to be (On Windows 7)

C:\Users\username\AppData\Roaming\Microsoft\Windows\Start Menu

For the All Users start menu (in Windows 7), it's

C:\ProgramData\Microsoft\Windows\Start Menu

However, only the admin and the user themselves will have unfettered access to each user's folders; everyone else will lack read/write permissions. You can circumvent this by running the program as admin, but you may wish to instead reconsider your program design, as a solution that depends on access to system-managed folders is, by design, going to be unstable.



来源:https://stackoverflow.com/questions/33089959/get-path-to-all-users-start-menu-on-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!