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

VC++ 創建 MSI 安裝包:從零開始構建專業級安裝程序

     編輯:C++ 入門

前言:為什麼需要 MSI 安裝包?

作為開發者,將軟件打包為 MSI 安裝包不僅顯得專業,還能實現註冊表寫入、桌面快捷方式創建、組件註冊等標準安裝行為。本文記錄使用 Windows Installer API (MSI.lib) 從零創建一個基本 MSI 數據庫文件的完整過程,並提供可編譯運行的 VC++ 示例代碼。

核心 API 流程解析

1. 打開/創建數據庫

使用 MsiOpenDatabase 配合 MSIDBOPEN_CREATEDIRECT 標誌創建新的 MSI 文件。若文件已存在則直接打開。錯誤處理通過 MsiGetLastErrorRecord 獲取錯誤記錄,再用 FormatMessage 轉換為可讀字符串。

2. 提交事務與關閉句柄

MsiDatabaseCommit 將所有更改持久化到磁盤,MsiCloseHandle 釋放資源。每一步都需檢查返回值是否為 ERROR_SUCCESS,失敗時彈出錯誤對話框並退出。

完整示例代碼

#pragma once
#include <tchar.h>
#include <Windows.h>
#pragma comment(lib, "msi.lib")
#include <Msi.h>
#include <MsiQuery.h>

INT APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, INT) {
    MSIHANDLE hDatabase = NULL;
    UINT result = MsiOpenDatabase(_T("Setup.msi"), MSIDBOPEN_CREATEDIRECT, &hDatabase);
    if (result != ERROR_SUCCESS) {
        ShowMsiError(result);
        return -1;
    }

    result = MsiDatabaseCommit(hDatabase);
    if (result != ERROR_SUCCESS) {
        ShowMsiError(result);
        MsiCloseHandle(hDatabase);
        return -1;
    }

    result = MsiCloseHandle(hDatabase);
    if (result != ERROR_SUCCESS) {
        ShowMsiError(result);
        return -1;
    }
    return 0;
}

void ShowMsiError(UINT errorCode) {
    MSIHANDLE hRec = MsiGetLastErrorRecord();
    LPVOID pMsg = NULL;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                  NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
                  (LPTSTR)&pMsg, 0, NULL);
    MessageBoxEx(NULL, (LPTSTR)pMsg, _T("MSI Error"), MB_OK,
                 MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT));
    LocalFree(pMsg);
}

進階:構建完整安裝邏輯

創建空數據庫只是第一步。真正的安裝包需要填充以下核心表:

  • Product 表:定義產品代碼、版本、製造商等元數據
  • Feature / Component 表:組織安裝功能樹與文件組件
  • File 表:列出所有需安裝的文件及屬性
  • Registry 表:註冊表寫入操作
  • Shortcut 表:創建開始菜單/桌面快捷方式
  • CustomAction 表:自定義安裝邏輯(如服務註冊)

可使用 MsiViewExecute 執行 SQL 插入語句填充表,或使用 ORCA 工具手動編輯驗證結構。建議從簡單的 "Hello World" 開始,逐步添加功能。

常見坑點與調試技巧

  1. GUID 生成:ProductCode、UpgradeCode、Component Code 必須使用合法 GUID,切勿硬編碼
  2. 序列表:InstallExecuteSequence、InstallUISequence 需正確排序標準動作
  3. 驗證工具:msival2 或 ORCA 的「驗證」功能可檢測 ICE 錯誤
  4. 日誌分析:安裝時添加 /l*v install.log 參數生成詳細日誌

總結與展望

本文實現了 MSI 文件的創建、提交、關閉最小閉環。後續工作包括:表結構設計、文件壓縮嵌入(CAB)、用戶界面定制、升級補丁支持等。MSI 數據庫關系複雜,建議參考《Windows Installer SDK》文檔,結合 ORCA 逆向分析成熟安裝包(如 Chrome、VS Code)的結構,漸進式掌握。

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