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

VC++ 替換 EXE 可執行檔圖示資源完整教學

     編輯:VC 教學

需求場景

安裝程式、啟動器或自動更新工具常需在不重新編譯的情況下替換目標 EXE 的圖示資源。Windows 提供 BeginUpdateResource / UpdateResource / EndUpdateResource 三大 API 實現資源修改。

核心步驟

  1. LoadLibrary 載入來源 EXE(含目標圖示)。
  2. FindResource / LoadResource / LockResource 取得圖示資源指標與大小。
  3. BeginUpdateResource 開啟目標 EXE 寫入模式(bDeleteExistingResources = FALSE 保留其他資源)。
  4. UpdateResource 寫入圖示群組(RT_GROUP_ICON)。
  5. EndUpdateResource 提交變更。

完整實現代碼

void ReplaceExeIcon(LPCTSTR srcExe, LPCTSTR dstExe, WORD srcIconId, WORD dstIconId)
{
    HMODULE hSrc = LoadLibraryEx(srcExe, NULL, LOAD_LIBRARY_AS_DATAFILE);
    if (!hSrc) { AfxMessageBox(_T("載入來源 EXE 失敗")); return; }

    HRSRC hRes = FindResource(hSrc, MAKEINTRESOURCE(srcIconId), RT_GROUP_ICON);
    if (!hRes) { AfxMessageBox(_T("找不到來源圖示資源")); FreeLibrary(hSrc); return; }

    HGLOBAL hResLoad = LoadResource(hSrc, hRes);
    LPVOID pData = LockResource(hResLoad);
    DWORD dwSize = SizeofResource(hSrc, hRes);

    HANDLE hUpdate = BeginUpdateResource(dstExe, FALSE);
    if (!hUpdate) { AfxMessageBox(_T("無法開啟目標 EXE 寫入")); FreeLibrary(hSrc); return; }

    BOOL ok = UpdateResource(hUpdate, RT_GROUP_ICON, MAKEINTRESOURCE(dstIconId),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), pData, dwSize);

    if (!ok || !EndUpdateResource(hUpdate, FALSE))
        AfxMessageBox(_T("資源更新失敗"));
    else
        AfxMessageBox(_T("圖示替換成功!"));

    FreeLibrary(hSrc);
}

// 使用範例:將 a.exe 的 IDI_ICON1 替換到 switch.exe 的 IDR_MAINFRAME
ReplaceExeIcon(_T("a.exe"), _T("switch.exe"), IDI_ICON1, IDR_MAINFRAME);

關鍵細節

  • 來源 EXE 必須以 LOAD_LIBRARY_AS_DATAFILE 載入,避免執行其入口點。
  • 圖示資源類型為 RT_GROUP_ICON,而非單一 RT_ICON,否則多解析度圖示會損壞。
  • 目標 EXE 不得正在執行,否則 BeginUpdateResource 會失敗(ERROR_ACCESS_DENIED)。
  • 若需替換多組圖示,重複呼叫 UpdateResource 並指定不同 dstIconId。

錯誤代碼速查

錯誤原因
ERROR_RESOURCE_DATA_NOT_FOUND來源資源 ID/類型錯誤
ERROR_ACCESS_DENIED目標檔案被鎖定或無寫入權限
ERROR_BAD_EXE_FORMAT目標非有效 PE 檔案
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved