这个让我卡了太久,所以我自答了。语气风趣,深表歉意!
试图使用官方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文件?
答案其实很简单。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");
}