Internet快捷方式对象IPersistFile::Save失败,出现E_FAIL(0x80004005)

问题描述 投票:0回答:1

这个让我卡了太久,所以我自答了。语气风趣,深表歉意!

试图使用官方API来创建.url文件,却只得到了 以下文件:

  • 使用CoCreateInstance创建一个Internet快捷方式对象的实例,使用CLSID_InternetShortcut的CLSID。
  • 使用IUniformResourceLocator::SetURL方法来设置快捷方式中的URL。
  • 使用IPersistFile::Save方法将快捷方式文件保存到所需的位置。

好的,所以应该是这样的(我的实际代码是生锈的,抱歉没有测试)。

CoInitializeEx(nullptr, 0);

IUniformResourceLocator* url = nullptr;
CoCreateInstance(
  CLSID_InternetShortcut,
  nullptr,
  CLSCTX_INPROC,
  IID_IUniformResourceLocator,
  (void**)&url,
);

哦,这在E_NOINTERFACE下失败了?好吧,现在代码还不多,所以不难猜到你要用STA初始化,而不是默认的MTA。

CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

所以这是第一步,第二步就是类似的东西了。

url->SetURL(L"https://stackoverflow.com", 0);

现在是第三步

IPersistFile* file = nullptr;
url->QueryInterface(IID_IPersistFile, (void**)&file);
file->Save(L"best-site.url", FALSE);

Huh, Save() 是返回E_FAIL?这就奇怪了,我用的是一模一样的代码将ShellLink对象保存到.lnk文件?

windows winapi com
1个回答
3
投票

答案其实很简单。InternetShortcut 不管是什么原因,不像... ShellLink 和其他可能的shell对象的路径要求是 Save() 是绝对的。(而且只有 Save(), Load() 是相当满意的相对路径)

所以,完整的工作代码使用 WIL:

#include <windows.h>
#include <IntShCut.h>
#include <wil/com.h>

void save_link(LPCWSTR url_value, LPCWSTR path) {
    auto url = wil::CoCreateInstance<IUniformResourceLocator>(CLSID_InternetShortcut, CLSCTX_INPROC);
    THROW_IF_FAILED(url->SetURL(url_value, 0));
    auto file = url.query<IPersistFile>();
    WCHAR full_path[MAX_PATH];
    GetFullPathName(path, ARRAYSIZE(full_path), full_path, nullptr);
    THROW_IF_FAILED(file->Save(full_path, FALSE));
}

int main() {
    THROW_IF_FAILED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED));
    save_link(L"https://stackoverflow.com", L"best-site.url");
}
© www.soinside.com 2019 - 2024. All rights reserved.