0

我有一个包装应用程序,它需要识别所有已发布的 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()正如预期的那样做同样的事情,但我看不到其他可以调用的方法可以获取我需要的数据。

我创建了一个具有不同参数样式(和plain)的测试快捷方式/param-paramparam没有任何区别。不只是 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 ..

4

1 回答 1

0

我发现了问题 - 输入快捷方式是 .lnk,但不是绝对文件路径;由于我的当前目录未设置为快捷方式所在的位置,这自然使其无法加载。

我让 Qt 遍历绝对路径,但是在搜索目标时我只传入了文件名。我在其他地方修改了我之前的电话:

file_info.fileName()

至:

file_info.absoluteFilePath()

这已经解决了这个问题!

于 2014-08-01T08:50:02.743 回答