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

.NET 安裝程序集成數據庫部署:自定義 Installer 實現建庫與腳本執行

     編輯:關於.NET

為實現「安裝即就緒」的交付體驗,將數據庫初始化腳本內嵌於安裝包,通過自定義 Installer 組件在安裝/卸載/回滾階段自動執行。本文展示基於 System.Configuration.Install 的完整實現方案。

架構設計

  • DBInstall 類庫:獨立專案,含 DBInstall.cs 繼承 Installer,標記 [RunInstaller(true)]。
  • 嵌入資源:SQL 腳本作為嵌入資源(Build Action = Embedded Resource)編譯入 DLL,避免外部文件依賴。
  • Setup 專案:引用 DBInstall 主輸出,在自定義動作中綁定四個階段。

核心代碼實現

1. 安裝類骨架

[RunInstaller(true)]
public partial class DBInstall : Installer {
    public override void Install(IDictionary stateSaver) { /* ... */ }
    public override void Uninstall(IDictionary savedState) { /* ... */ }
    public override void Rollback(IDictionary savedState) { /* ... */ }
}

2. 安裝階段:建庫與執行腳本

public override void Install(IDictionary stateSaver) {
    base.Install(stateSaver);
    if (MessageBox.Show("安裝數據庫?", "確認", MessageBoxButtons.YesNo) == DialogResult.Yes) {
        var cfg = new DBConfig();  // 自定義輸入框:Server/User/Pwd
        cfg.ShowDialog();

        SaveParams(cfg.IP, cfg.DBUser, cfg.DBPwd);  // 存入 Context.Parameters

        string dbName = "MyAppDB";
        ExecuteSql("master", $"CREATE DATABASE [{dbName}]");
        string sql = LoadSqlFromAssembly("MyApp.DB.Init.sql");
        ExecuteSql(dbName, sql);
    }
}

3. 協載與執行 SQL 腳本

private string LoadSqlFromAssembly(string name) {
    var asm = Assembly.GetExecutingAssembly();
    using (var stream = asm.GetManifestResourceStream(asm.GetName().Name + "." + name))
    using (var reader = new StreamReader(stream))
        return reader.ReadToEnd();
}

private void ExecuteSql(string dbName, string sql) {
    var conn = new SqlConnection(
        $"user id={Context.Parameters["user"]};" +
        $"data source={Context.Parameters["dbsource"]};" +
        $"initial catalog=master;password={Context.Parameters["pwd"]};");
    var cmd = new SqlCommand(sql, conn);
    cmd.Connection.Open();
    cmd.Connection.ChangeDatabase(dbName);
    try { cmd.ExecuteNonQuery(); }
    finally { cmd.Connection.Close(); }
}

4. 卸載與回滾:安全清理

public override void Uninstall(IDictionary savedState) {
    base.Uninstall(savedState);
    if (MessageBox.Show("移除數據庫?", "確認", MessageBoxButtons.YesNo) == DialogResult.Yes) {
        var cfg = new DBConfig(); cfg.ShowDialog();
        SaveParams(cfg.IP, cfg.DBUser, cfg.DBPwd);
        ExecuteSql("master", "DROP DATABASE [MyAppDB]");
    }
}

public override void Rollback(IDictionary savedState) {
    base.Rollback(savedState);
    // 安裝失敗時清理殘留庫
    if (MessageBox.Show("回滾時刪除數據庫?", "確認", MessageBoxButtons.YesNo) == DialogResult.Yes)
        ExecuteSql("master", "DROP DATABASE [MyAppDB]");
}

Setup 專案配置要點

  1. 創建 Setup Project,右鍵「添加」→「專案輸出」→ 選擇 DBInstall 專案的「主輸出」。
  2. 檢視 → 自定義動作,在 Install/Commit/Rollback/Uninstall 四節點下各添加一次「主輸出」。
  3. 編譯生成 .msi,雙擊安裝即觸發完整流程。

關鍵避坑指南

  • SQL 腳本去 GO:ExecuteNonQuery 不支持 GO 批次分隔符,腳本需拆分為單條語句或手動分批執行。
  • 參數持久化:Context.Parameters 在 Install/Uninstall/Rollback 間自動流轉,無需外部存儲。
  • UI 線程阻塞:ShowDialog() 會阻塞安裝進程,確保用戶輸入同步獲取。
  • 異常處理:所有 DB 操作包裹在 try-catch,友好提示而非拋出原始異常導致安裝崩潰。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved