-Windows 7 64位
-Visual Studio 2013(v120)
-已启用Unicode
-Target Build- Debug 32-bit
我想构建一个启动器(供个人使用),但是我无法让ShellExecute使用所有文件类型或路径,特别是快捷方式(LNK)。我已经研究和尝试了以下多种组合...
-我正在使用转义序列
-我正在添加文件扩展名(并且尝试不使用)
-我包含了Windows.h
-打印目录FindFirstFile / FindNextFile,以明确确保路径没有错别字
-尝试使用文字和变量作为文件路径参数
-尝试以管理员权限运行VS
-尝试使用ShellExecute,ShellExecuteA,ShellExecuteEx和System(具有适当的字符集)
-动词尝试NULL,“ runas”和“ open”
-使用相同的路径从命令行或资源管理器中正常启动
-尝试使用%USERPROFILE%宏代替用户名(返回2)
-似乎可以使用EXE和URL
-似乎无法在包括C:\在内的任何路径上直接与任何LNK一起使用
疑似问题
-32bit / 64bit差异
-UAC /惊喜
-字符集
-文件扩展名
-防病毒干扰(尽管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;
}
答案 0 :(得分:1)
首先,检查.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
,此问题将得到解决。