简体   繁体   English

InternetShortcut object IPersistFile::Save 失败并显示 E_FAIL (0x80004005)

[英]InternetShortcut object IPersistFile::Save fails with E_FAIL (0x80004005)

This one had me stuck for too long, so I'm self answering this.这个让我卡了太久,所以我自己回答这个问题。 Apologies for the sardonic tone!为讽刺的语气道歉!

Trying to use the official API to create.url files has only the following documentation :尝试使用官方 API 创建.url 文件只有以下文档

  • Create an instance of the Internet shortcut object with CoCreateInstance, using a CLSID of CLSID_InternetShortcut.使用 CLSID_InternetShortcut 的 CLSID 使用 CoCreateInstance 创建 Internet 快捷方式 object 的实例。
  • Use the IUniformResourceLocator::SetURL method to set the URL in the shortcut.使用 IUniformResourceLocator::SetURL 方法在快捷方式中设置 URL。
  • Use the IPersistFile::Save method to save the shortcut file to a desired location.使用 IPersistFile::Save 方法将快捷方式文件保存到所需位置。

Ok, so that should look something like this (my actual code is rust, sorry for the lack of testing):好的,应该看起来像这样(我的实际代码是 rust,抱歉缺乏测试):

CoInitializeEx(nullptr, 0);

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

Oh this fails with E_NOINTERFACE?哦,E_NOINTERFACE 失败了? Well there's not much code yet, so it's not too hard to guess that you have to init with STA, instead of the default MTA:好吧,还没有太多代码,所以不难猜测您必须使用 STA 进行初始化,而不是使用默认的 MTA:

CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

So that's the first step, the second is just something like:所以这是第一步,第二步是这样的:

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

Now for the third step:现在进行第三步:

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

Huh, Save() is returning E_FAIL?嗯, Save()正在返回 E_FAIL? That's strange, I'm using exactly the same code for saving a ShellLink object to a.lnk file?这很奇怪,我使用完全相同的代码将 ShellLink object 保存到 .lnk 文件?

The answer is actually quite simple: InternetShortcut for whatever reason, unlike ShellLink and presumably other shell objects requires that the path for Save() is absolute.答案实际上很简单:无论出于何种原因, InternetShortcut都与ShellLink和可能的其他 shell 对象不同,它要求Save()的路径是绝对的。 (And only Save() , Load() is quite happy with a relative path) (而且只有Save()Load()对相对路径非常满意)

So, the full working code using WIL :因此,使用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");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Windows Search SQL:LIKE语句中的分号导致异常(E_FAIL 0x80004005) - Windows Search SQL: Semicolon in LIKE statement causes exception (E_FAIL 0x80004005) Windows 10 上的 genymotion“无法加载 virtualbox 引擎”和 Virtualbox 错误“结果代码:E_FAIL (0x80004005)” - genymotion "unable to load virtualbox engine" on windows 10 and Virtualbox error " Result Code: E_FAIL (0x80004005)" 为什么 AllocateStreamingResources 会失败并显示错误代码 0x80004005? - Why would AllocateStreamingResources fail with error code 0x80004005? 开发人员解锁Windows Phone 8获取0x80004005 - Developer Unlock Windows Phone 8 getting 0x80004005 Media Foundation自定义拓扑E_FAIL - Media Foundation Custom Topology E_FAIL 蓝牙Microsoft鼠标连接Windows 7 64的错误代码0x80004005 - Error code 0x80004005 for Bluetooth Microsoft Mouse connection Windows 7 64 OleDbException (0x80004005):未找到 Oracle 客户端和网络组件。 我怎样才能解决这个问题? - OleDbException (0x80004005): Oracle client and networking components were not found. How can I fix this? 使用 net 调试目标计算机 (VM) 时,WinDbg 失败并出现错误 0x80004005 - WinDbg failed with error 0x80004005 when debugging target machine (VM) using net 错误 80004005 安装 vc.redis.x64 - error 80004005 installing vc.redis.x64 URLDownloadToFile失败,代码为0x800c0008(INET_E_DOWNLOAD_FAILURE) - URLDownloadToFile fails with code 0x800c0008 (INET_E_DOWNLOAD_FAILURE)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM