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

VC++ 專案中使用自訂資源嵌入二進位檔案

     編輯:關於VC++

前言

除了對話框、選單、位圖等標準資源類型,VC++ 支援 自訂資源 (Custom Resource),可將任意二進位檔案 (ZIP、DLL、AVI、加密資料…) 直接嵌入 EXE/DLL,執行時從資源載入釋放,適用於:

  • 內建預設皮膚/語言包 (防止外部檔案遺失)
  • 嵌入相依 DLL 簡化部署 (單一 EXE 發行)
  • 內建教學影片/範本檔案
  • 惡意軟體釋放載荷 (惡意用途,僅供防禦研究)

資源加入步驟

  1. 方案總管 → 右鍵專案 → Add Resource → 選 Custom → 輸入自訂類型名稱 (如 MYTYPE)。
  2. IDE 建立二進位資源節點,點擊 Import 選取目標檔案 (如 skin.zip)。
  3. 資源 ID 自動指派 (如 IDR_MYTYPE1),類型顯示為 MYTYPE。

核心 API 流程

// 1. 定位資源
HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_MYTYPE1), _T("MYTYPE"));
if (!hRsrc) return FALSE;

// 2. 取得資源大小
DWORD dwSize = SizeofResource(NULL, hRsrc);
if (!dwSize) return FALSE;

// 3. 載入資源到記憶體
HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
if (!hGlobal) return FALSE;

// 4. 鎖定取得資料指標
LPVOID pBuffer = LockResource(hGlobal);
if (!pBuffer) return FALSE;

// 5. 使用資料 (寫入檔案/記憶體載入 DLL/解壓縮...)
FILE* fp = _tfopen(_T("released.bin"), _T("wb"));
if (fp) {
    fwrite(pBuffer, 1, dwSize, fp);
    fclose(fp);
}

// 6. Win32 下無需 UnlockResource/FreeResource (16-bit 遺留 API,系統自動回收)
return TRUE;

完整範例函式

BOOL UseCustomResource()
{
    HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(ITEMID), TEXT("MyType"));
    if (!hRsrc) return FALSE;

    DWORD dwSize = SizeofResource(NULL, hRsrc);
    if (!dwSize) return FALSE;

    HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
    if (!hGlobal) return FALSE;

    LPVOID pBuffer = LockResource(hGlobal);
    if (!pBuffer) return FALSE;

    BOOL bRt = FALSE;
    FILE* fp = _tfopen(_T("demo.exe"), _T("wb"));
    if (fp) {
        if (dwSize == fwrite(pBuffer, 1, dwSize, fp)) bRt = TRUE;
        fclose(fp);
    }
    return bRt;
}

實戰 Demo:模擬 WinZip Self-Extractor

專案嵌入兩項自訂資源:

  • HELLO_EXE (類型 EMBED_EXE):一個 Win32 Hello World 程式
  • PROJECT_ZIP (類型 EMBED_ZIP):整個專案原始碼壓縮包

介面提供 [Release] 釋放 Hello World、[Unzip] 解壓專案原始碼 (需配合 zlib/miniz 等解壓庫)。

進階應用:嵌入 DLL 並在記憶體載入

// 釋放到暫存檔再 LoadLibrary (簡單但需寫磁碟)
WriteResourceToTempFile(IDR_MYDLL, "MYDLL", _T("mylib.dll"));
HMODULE hMod = LoadLibrary(_T("mylib.dll"));

// 純記憶體載入 (需手動解析 PE 結構,或使用開源 MemoryModule)
HMODULE hMod = MemoryLoadLibrary(pBuffer, dwSize);

注意事項

  • 資源會增加 EXE 體積,大型檔案建議外部發布或網路下載。
  • 嵌入 DLL 可能觸發殺毒軟體誤報,簽章與白名單處理需謹慎。
  • 64 位元專案嵌入 32 位元 DLL 需分離架構或使用 WoW64 重導向。
  • 資源 ID 建議使用符號常數而非數字,利於維護。

完整原始碼 (WinXP + VC.NET 2003 + WTL 7.5 編譯通過) 可下載參考。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved