-Windows 7 64位 -Visual Studio 2013(v120) -Unicode已启用 -Target Build- Debug 32-bit
我想构建一个启动器(供个人使用)但是我不能让ShellExecute使用所有文件类型或路径,特别是快捷方式(LNK)。我已经研究并尝试了以下许多组合... - 我正在使用转义序列 - 我正在添加文件扩展名(并且没有尝试) - 我已经包含了Windows.h. - 打印目录FindFirstFile / FindNextFile以明确确保路径没有拼写错误 - 使用文字和变量作为文件路径参数 - 使用管理员权限运行VS. -Tried ShellExecute,ShellExecuteA,ShellExecuteEx和System(带有适当的字符集) -Tried NULL,“runas”和动词“打开” - 使用相同路径从命令行或资源管理器中启动 -Tried使用%USERPROFILE%宏而不是用户名(返回2) - 使用EXE和URL - 似乎不能在任何路径上使用任何LNK,包括C:\直接
疑似问题 -32bit / 64bit差异 -UAC / Privelages -字符集 -文件扩展名 - 抗病毒干扰(虽然AV没有提醒我任何问题)我已经测试了同时沉默我的AV
这是我尝试过的最简单的程序之一......
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <atlstr.h>
int _tmain(int argc, _TCHAR* argv[])
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
// Variables below for testing as path argument
// Paths that end with LNK are the only ones that I can't get to launch
CStringW link("C:\\Users\\Home\\Documents\\Art\\blender.lnk"); // Doesn't work
CStringW target("C:\\Program Files\\Blender Foundation\\Blender\\blender.exe"); // Launches software as expected
CStringW url("https://stackoverflow.com"); // Launches browser with URL as expected
int error = reinterpret_cast<int>(ShellExecute(
NULL,
NULL,
L"C:\\Users\\Home\\Documents\\Art\\blender.lnk", // Using literal with LNK extension also does not work
NULL,
NULL,
SW_SHOWDEFAULT
));
// EVEN SYSTEM CAN NOT FIND THE PATH!!!
// system("C:\\Users\\Home\\Documents\\Art\\blender.lnk");
std::cout << error << std::endl; // Returns 3 "The specified path was not found.".
// Free COM
CoUninitialize();
return 0;
}
首先,检查您的.lnk文件是否在路径中。
然后(以及问题的最可能原因)检查您的.lnk文件名是否正确创建。为了确保它不像“blender.lnk.lnk”(如果我设置为此,我可以重现你的问题)。
您也可以尝试自己手动解析链接文件的路径。这是样本:
void ShortcutToRealpath(LPWSTR pszString, LPSTR pdzString)
{
IShellLink *pShellLink;
HRESULT hRes;
::CoInitialize(NULL);
hRes = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&pShellLink);
if (SUCCEEDED(hRes))
{
IPersistFile *ppf;
hRes = pShellLink->QueryInterface(IID_IPersistFile, (void **)&ppf);
if (SUCCEEDED(hRes))
{
hRes = ppf->Load(pszString, TRUE);
if (SUCCEEDED(hRes))
{
pShellLink->GetPath(pdzString, MAX_PATH, NULL, 0);
}
ppf->Release();
}
pShellLink->Release();
}
::CoUninitialize();
}
当我构建为x86平台时,路径将被解析为:这就是你的程序无法找到路径的原因。
将目标文件放到相应的文件中。
编辑:
在我使用MS工具Procmom.exe测试之后,我发现了其他的东西,如果以32位运行,它将显示:
关键值是C:\Program Files (x86)
,如果我们将其作为64位运行,则键是引用“HKLM \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ ProgramFilesDir”,键值为C:\Program Files
。我检查注册表后:
似乎
C:\Program Files
默认不可见到32位注册表(我不确定具体原因)。如果在32位注册表中将密钥ProgramFilesDir
更改为C:\Program Files
,则问题将得到解决。