首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Windows 桌面建立捷徑完整指南:IShellLink 實作與 COM 簡化技巧

     編輯:關於C++

基本原理

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 與等效 C++ 程式碼對照

別陷入 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(Link);
pPersistFile->Save(...)PersistFile->Save(...)
pPersistFile->Release(); pLink->Release();delete PersistFile; delete Link;
CoUninitialize();(隱含清理)

關鍵 API 說明

  • SHGetSpecialFolderLocation(CSIDL_DESKTOPDIRECTORY):取得桌面目錄 PIDL,支援多使用者、重導向等情境
  • SHGetMalloc / IMalloc::Free:正確釋放 PIDL 記憶體
  • IPersistFile::Save(c_bstr(), TRUE):TRUE 表示覆蓋既有檔案

常見陷阱

  1. 未呼叫 CoInitialize/CoUninitialize 導致 COM 操作失敗
  2. 直接寫死 C:\Windows\Desktop 不支援使用者配置檔重導向
  3. 忘記釋放 IMalloc 與 PIDL 造成記憶體洩漏
  4. 路徑未轉 Unicode (WideString/c_bstr()) 導致儲存失敗
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved