我有一个包装器应用程序,需要识别所有已发布的XP Mode应用程序;这些都存在于一个文件夹中,我使用Qt获取所有.lnk文件。
这个位有效 - 问题是,所有Virtual PC应用程序都使用rundll32来启动虚拟机和/或其应用程序(例如%SystemRoot%\system32\rundll32.exe %SystemRoot%\system32\VMCPropertyHandler.dll,LaunchVMSal "Windows XP Mode" "||some_id" "some_name"
),因此我需要读取完整目标。
阅读MSDN文档,GetArguments()
上的IShellLink
应返回此数据 - 但它只检索rundll32.exe
的路径,并且永远不会使用任何尾随的命令行数据。正如预期的那样,GetPath()
做了同样的事情,但是我没有看到其他方法可以调用它来获取我需要的数据。
我创建了一个具有不同参数样式的测试快捷方式(/param
,-param
和普通param
),但没有任何区别。它不仅仅是具有故障的Virtual PC链接 - 这适用于所有快捷方式。
这是功能代码:
QString GetShortcutTarget(const char* shortcut)
{
IShellLink* psl = NULL;
IPersistFile* ppf = NULL;
wchar_t wsz[MAX_PATH];
wchar_t target[MAX_PATH * 4]; // w/e
QString retval;
if ( MultiByteToWideChar(CP_ACP, 0, shortcut, -1, wsz, MAX_PATH) == 0 )
goto cleanup;
if ( FAILED(CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl)) )
goto cleanup;
if ( FAILED(psl->QueryInterface(IID_IPersistFile, (void **)&ppf)) )
goto cleanup;
if ( FAILED(ppf->Load(wsz, STGM_READ)) )
goto cleanup;
// GetPath() and GetArguments return the same
//if ( NOERROR != psl->GetPath(target, _countof(target), nullptr, 0) )
if ( NOERROR != psl->GetArguments(target, _countof(target)) )
goto cleanup;
retval = QString::fromWCharArray(target);
cleanup:
if ( ppf )
ppf->Release();
if ( psl )
psl->Release();
return retval;
}
修改
不在任何地方重新定义界面,包括和链接:
#include <objidl.h> // IPersistFile
#include <shlobj.h> // IShellLink
#pragma comment ( lib, "ole32.lib" )
#pragma comment ( lib, "uuid.lib" )
只有其他COM相关的代码在构造函数和析构函数的其他地方(是的,已经被调用了!):
CoInitialize(NULL);
...
CoUninitialize();
Qt希望不应该与它有任何关系,因为COM肯定会打开并阅读.lnk ..
答案 0 :(得分:0)
我发现了问题 - 输入快捷方式是.lnk,但不是绝对文件路径;由于我的当前目录未设置为快捷方式所在的位置,因此无法加载。
我有Qt迭代绝对路径,但我只是在搜索目标时传递文件名。我在其他地方修改过我之前的电话:
file_info.fileName()
为:
file_info.absoluteFilePath()
这解决了这个问题!