获取 Windows 上所有用户开始菜单的路径
Get path to all users' start menu on Windows
我正在寻找一种方法来检索 C++ 中所有用户开始菜单目录的路径。我只能获得当前用户之一(使用 Qt):
QString startMenuPath = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).at(0);
但是,Qt 不允许为所有用户检索一个。据我所知,也没有包含该路径的环境变量,我可以阅读。
任何用户开始菜单的路径将是(On Windows 7)
C:\Users\username
\AppData\Roaming\Microsoft\Windows\Start Menu
对于“所有用户”开始菜单(在 Windows 7 中),它是
C:\ProgramData\Microsoft\Windows\Start Menu
但是,只有管理员和用户自己可以不受限制地访问每个用户的文件夹;其他人将缺少 read/write 权限。您可以通过 运行 程序作为管理员来规避此问题,但您可能希望重新考虑您的程序设计,因为根据设计,依赖于访问系统管理文件夹的解决方案将变得不稳定。
要获取已知文件夹,请对所需文件夹使用 SHGetFolderPath
, and pass a KNOWNFOLDERID
or CSIDL
。
例如,以下代码获取所有用户 Start Menu
和 Programs
文件夹:
// 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;
感谢用户 theB 提供的解决方案。这是我在 Windows(使用 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;
}
我正在寻找一种方法来检索 C++ 中所有用户开始菜单目录的路径。我只能获得当前用户之一(使用 Qt):
QString startMenuPath = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).at(0);
但是,Qt 不允许为所有用户检索一个。据我所知,也没有包含该路径的环境变量,我可以阅读。
任何用户开始菜单的路径将是(On Windows 7)
C:\Users\
username
\AppData\Roaming\Microsoft\Windows\Start Menu
对于“所有用户”开始菜单(在 Windows 7 中),它是
C:\ProgramData\Microsoft\Windows\Start Menu
但是,只有管理员和用户自己可以不受限制地访问每个用户的文件夹;其他人将缺少 read/write 权限。您可以通过 运行 程序作为管理员来规避此问题,但您可能希望重新考虑您的程序设计,因为根据设计,依赖于访问系统管理文件夹的解决方案将变得不稳定。
要获取已知文件夹,请对所需文件夹使用 SHGetFolderPath
, and pass a KNOWNFOLDERID
or CSIDL
。
例如,以下代码获取所有用户 Start Menu
和 Programs
文件夹:
// 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;
感谢用户 theB 提供的解决方案。这是我在 Windows(使用 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;
}