IPersistFile加载未定义的返回值

时间:2014-07-30 13:38:46

标签: c++ qt winapi mingw

我目前正在尝试将MSDN上的示例Resolving a Shortcut移植到使用MinGW 4.8.1构建的QT应用程序。

我的代码(剥离错误检查的简短性)目前看起来像这样:

QFileInfo shortcut("C:\\Users\\MyUserName\\ShortCut.lnk");

HRESULT apiResult;
IShellLink *shellLink;

apiResult = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
                             IID_IShellLink, (LPVOID*) &shellLink);

IPersistFile *persistFile;
apiResult = shellLink->QueryInterface(IID_IPersistFile, (void**) &persistFile);

WCHAR shortcutLocationWchar[MAX_PATH];
QString shortcutLocation = QDir::toNativeSeparators(shortcut.absoluteFilePath());
shortcutLocation.toWCharArray(shortcutLocationWchar);

apiResult = persistFile->Load(shortcutLocationWchar, STGM_READ);

apiResult = shellLink->Resolve(NULL, SLR_NO_UI);

WCHAR shortcutTargetWchar[MAX_PATH];
WIN32_FIND_DATA winFindData;
apiResult = shellLink->GetPath(shortcutTargetWchar, MAX_PATH, &winFindData, 0);

QString shortcutTarget = QString::fromWCharArray(shortcutTargetWchar);

目前IPersistFile::Load失败且返回值为0x80070002its API Document中既未定义,winerr.h标题也未定义,Google似乎没有提供任何有用的结果。

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

返回值0x80070002表示系统找不到指定的文件。因此,您的文件路径不正确。我认为你应该把它写成:

QFileInfo shortcut("C:\\Users\\MyUserName\\ShortCut.lnk");

我还会通过以下方式简化您的代码:

QString shortcutLocation = shortcut.absoluteFilePath();
apiResult = persistFile->Load((LPCWSTR)shortcutLocation.constData(), STGM_READ);

最后,为什么你需要使用Windows API,并将它与Qt混合,当你可以使用更简单,更短的完全基于Qt的解决方案时。例如,我会这样做:

QFileInfo shortcut(QFileInfo shortcut("D:\\downloads\\sk.lnk.lnk");
QString shortcutTarget ;
if (shortcut.isSymLink()) {
    shortcutTarget = shortcut.symLinkTarget();
}

答案 1 :(得分:0)

我错过了API documentation for QString::toWcharArrar()中的重要一行:

  

注意:此函数不会向数组附加空字符。

所以正确的方法是将快捷方式文件名转换为WCHAR数组

WCHAR shortcutLocationWchar[MAX_PATH];
QString shortcutLocation = QDir::toNativeSeparators(shortcut.absoluteFilePath());
int l = shortcutLocation.toWCharArray(shortcutLocationWchar);
shortcutLocationWchar[l] = L'\0';