Windows 提供 IShellLink COM 介面建立捷徑。流程:建立物件 → 設定屬性 → 透過 IPersistFile::Save 儲存至桌面目錄。
#define NO_WIN32_LEAN_AND_MEAN
#include
#include
void TForm1::CreateShortCut(const AnsiString &file) {
IShellLink *pLink;
IPersistFile *pPersistFile;
if (SUCCEEDED(CoInitialize(NULL))) {
if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void**)&pLink))) {
pLink->SetPath(file.c_str());
pLink->SetDescription("哈哈,你看到我了吧.");
pLink->SetShowCmd(SW_SHOW);
if (SUCCEEDED(pLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile))) {
WideString strShortCutLocation("C:\\bcbshortcut.lnk");
pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE);
pPersistFile->Release();
}
pLink->Release();
}
CoUninitialize();
}
}
void TForm1::CreateShortCut(const AnsiString &file) {
IShellLink *pLink;
IPersistFile *pPersistFile;
LPMALLOC ShellMalloc;
LPITEMIDLIST DesktopPidl;
char DesktopDir[MAX_PATH];
// 1. 取得 Shell 記憶體配置器
if (FAILED(SHGetMalloc(&ShellMalloc))) return;
// 2. 取得桌面目錄 PIDL
if (FAILED(SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &DesktopPidl))) return;
// 3. 轉換為檔案系統路徑
if (!SHGetPathFromIDList(DesktopPidl, DesktopDir)) {
ShellMalloc->Free(DesktopPidl);
ShellMalloc->Release();
return;
}
ShellMalloc->Free(DesktopPidl);
ShellMalloc->Release();
// 4. 建立捷徑並儲存至桌面
if (SUCCEEDED(CoInitialize(NULL))) {
if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void**)&pLink))) {
pLink->SetPath(file.c_str());
pLink->SetDescription("哈哈,你看到我了吧.");
pLink->SetShowCmd(SW_SHOW);
if (SUCCEEDED(pLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile))) {
WideString strShortCutLocation(DesktopDir);
strShortCutLocation += "\\bcbshortcut.lnk";
pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE);
pPersistFile->Release();
}
pLink->Release();
}
CoUninitialize();
}
}
別陷入 COM 複雜度泥沼,概念對照:
| COM 寫法 | 等效 C++ 概念 |
|---|---|
IShellLink* pLink; | TShellLink *Link; |
IPersistFile* pPersistFile; | TPersistFile *PersistFile; |
CoInitialize(); | (隱含物件模型初始化) |
CoCreateInstance(...) | Link = new TShellLink; |
pLink->SetPath(...) | Link->SetPath(...) |
pLink->QueryInterface(...) | PersistFile = dynamic_cast |
pPersistFile->Save(...) | PersistFile->Save(...) |
pPersistFile->Release(); pLink->Release(); | delete PersistFile; delete Link; |
CoUninitialize(); | (隱含清理) |
SHGetSpecialFolderLocation(CSIDL_DESKTOPDIRECTORY):取得桌面目錄 PIDL,支援多使用者、重導向等情境SHGetMalloc / IMalloc::Free:正確釋放 PIDL 記憶體IPersistFile::Save(c_bstr(), TRUE):TRUE 表示覆蓋既有檔案CoInitialize/CoUninitialize 導致 COM 操作失敗C:\Windows\Desktop 不支援使用者配置檔重導向IMalloc 與 PIDL 造成記憶體洩漏