【发布时间】:2020-09-04 22:55:34
【问题描述】:
这个问题让我卡了太久,所以我自己回答这个问题。为讽刺的语气道歉!
尝试使用官方API创建.url文件只有the following documentation:
- 使用 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);
嗯,Save() 正在返回 E_FAIL?这很奇怪,我使用完全相同的代码将 ShellLink 对象保存到 .lnk 文件?
【问题讨论】:
-
“不难猜到你必须用 STA 来初始化,而不是默认的 MTA”——听起来像是 Raymond Chen 写博客解释原因的工作
IUniformResourceLocator在 MTA 中不起作用;-) 不过,this port 总结道:“我的猜测是,InternetShortcut 被标记为单元线程对象,并且 IUniformResourceLocator 接口不可编组。 i>" -
我猜测为什么它被标记为单元线程是 IURL 有一个带有 HWND 参数的调用方法,因此可能有时会显示 UI(浏览器选择?)。如果您只想设置 URL,这很烦人,也许您可以在 MTA 中获取
IPropertySetStore?值得测试。