我尝试在StartMenu文件夹中创建指向文件的链接,我的代码为:
bool createStartMenuEntry(string targetPath, string name){
std::wstring stemp = s2ws(targetPath);
LPCWSTR target = stemp.c_str();
WCHAR startMenuPath[MAX_PATH];
HRESULT result = SHGetFolderPathW(NULL, CSIDL_COMMON_PROGRAMS, NULL, 0, startMenuPath);
if (SUCCEEDED(result)) {
std::wstring linkPath = std::wstring(startMenuPath) + s2ws(name);
LPCWSTR link = linkPath.c_str();
//TEST MESSAGE!!!
MessageBox(NULL, LPCSTR(target), LPCSTR(link), MB_ICONWARNING);
CoInitialize(NULL);
IShellLinkW* shellLink = NULL;
result = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkW, (void**)&shellLink);
if (SUCCEEDED(result)) {
shellLink->SetPath(target);
//shellLink->SetDescription(L"Shortcut Description");
shellLink->SetIconLocation(target, 0);
IPersistFile* persistFile;
result = shellLink->QueryInterface(IID_IPersistFile, (void**)&persistFile);
if (SUCCEEDED(result)) {
result = persistFile->Save(link, TRUE);
persistFile->Release();
}
else {
return false;
}
shellLink->Release();
}
else {
return false;
}
}
else {
return false;
}
return true;
}
字符串到宽字符串转换:
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
当我像createStartMenuEntry("E:\\file.exe" , "File")
那样调用我的func时,在测试消息中我只有第一个路径字母而快捷方式未创建,我认为是unicode转换中的问题。
答案 0 :(得分:2)
这里有很多问题:
MessageBox(NULL, LPCSTR(target), LPCSTR(link), MB_ICONWARNING);
是各种错误的。你不应该像这样投射字符串。如果您在未定义UNICODE
的情况下进行编译,则必须使用MessageBoxW()
来显示LPCWSTR
字符串。您得到一个字符,因为"c:\\"
作为Unicode字符串在内存中是'c',0,':',0,'\\',0,0,0
,并且当被视为窄ANSI字符串时,它与"c"
字符串相同。persistFile->Save()
的结果!您还会忽略SetPath()
和SetIconLocation()
。CSIDL_COMMON_PROGRAMS
,只有管理员具有该文件夹的写入权限,因为它由所有用户共享。如果您不打算要求UAC提升,则必须改为CSIDL_PROGRAMS
。std::string
来存储路径,只能使用std::wstring
和WCHAR*
/ LP[C]WSTR
,因为包含某些Unicode字符的路径无法用窄的ANSI字符串表示