问题
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