前段時間做一個項目,因為其中數據庫有許多數據是初始化的數據, 為了便於部署.於是我在制作安裝程序的時候加入了 DB install的功能.
首先最好單獨創建一個DB install 的Class Library的Project.
Fileà NewàProjectàVisual C# à WindowsàClass Library
然後創建一個class, 命名為DBInstall.cs. 下面就是如何在這個class 中實現DB"安裝"的過程.
首先需要將 DBInstall 繼承 Installer class. 還需要加上[RunInstaller(true)]的attribute.
繼承
1[RunInstaller(true)] 2 3public partial class DBInstall : Installer 4
此時圖標會由變為, 說明這個class 已經成為了安裝的組件了.
然後就是 override Rollback, Uninstall, Install 三個方法:
Override Install Method
1 public override void Rollback(System.Collections.IDictionary savedState)
2
3 {
4
5 base.Rollback(savedState);
6
7
8
9 if (MessageBox.Show("Do you want to remove exist databases during rollback?", "Confirm", MessageBoxButtons.YesNo)
10
11 == DialogResult.Yes)
12
13 {
14
15 string dbname = "XXX"; //XXX 代表數據庫名稱
16
17 try
18
19 {
20
21 ExecuteSql("master", string.Format("DROP DATABASE [{0}]", dbname)); //回滾的時候刪除數據庫文件
22
23 }
24
25 catch
26
27 {
28
29 MessageBox.Show(string.Format("Can not delete [{0}] database. Please delete it by yourself."), dbname);
30
31 }
32
33
34
35 }
36
37 }
38
39
40
41 public override void Uninstall(System.Collections.IDictionary savedState)
42
43 {
44
45 base.Uninstall(savedState);
46
47
48
49 try
50
51 {
52
53 if (MessageBox.Show("Do you want to remove databases?", "Confirm", MessageBoxButtons.YesNo)
54
55 == DialogResult.Yes)
56
57 {
58
59 DBConfig dbConfig = new DBConfig(); //自定義的一個界面,便於輸入DB的信息
60
61 dbConfig.ShowDialog(); //安裝過程中顯示自定義的數據DB安裝信息的節目
62
63
64
65 if (this.Context.Parameters.ContainsKey("dbsource")) //用自定義的界面輸入的信息賦值給Context.Parameter,它主要負責記錄install和uninstall過程中的參數
66
67 {
68
69 this.Context.Parameters["dbsource"] = DBConfig.IP;
70
71 }
72
73 else
74
75 {
76
77 this.Context.Parameters.Add("dbsource", DBConfig.IP);
78
79 }
80
81 if (this.Context.Parameters.ContainsKey("user")) //用自定義的界面輸入的信息賦值給Context.Parameter,它主要負責記錄install和uninstall過程中的參數
82
83 {
84
85 this.Context.Parameters["user"] = DBConfig.DBUser;
86
87 }
88
89 else
90
91 {
92
93 this.Context.Parameters.Add("user", DBConfig.DBUser);
94
95 }
96
97 if (this.Context.Parameters.ContainsKey("pwd")) //用自定義的界面輸入的信息賦值給Context.Parameter,它主要負責記錄install和uninstall過程中的參數
98
99 {
100
101 this.Context.Parameters["pwd"] = DBConfig.DBPwd;
102
103 }
104
105 else
106
107 {
108
109 this.Context.Parameters.Add("pwd", DBConfig.DBPwd);
110
111 }
112
113 string dbname = "XXX"; // 數據庫的名稱
114
115 try
116
117 {
118
119 ExecuteSql("master", string.Format("DROP DATABASE [{0}]", dbname));
120
121 }
122
123 catch
124
125 {
126
127 MessageBox.Show(string.Format("Can not delete [{0}] database. Please delete it by your self."), dbname);
128
129 }
130
131 }
132
133 }
134
135 catch (Exception ex)
136
137 {
138
139 MessageBox.Show("Can not delete some databases, please delete them manually.");
140
141 }
142
143 }
144
145
146
147 public override void Install(System.Collections.IDictionary stateSaver)
148
149 {
150
151 base.Install(stateSaver);
152
153
154
155 if (MessageBox.Show("Do you want to install databases?", "Confirm", MessageBoxButtons.YesNo)
156
157 == DialogResult.Yes)
158
159 {
160
161 DBConfig dbConfig = new DBConfig();
162
163 dbConfig.ShowDialog();
164
165 if (this.Context.Parameters.ContainsKey("dbsource"))
166
167 {
168
169 this.Context.Parameters["dbsource"] = DBConfig.IP;
170
171 }
172
173 else
174
175 {
176
177 this.Context.Parameters.Add("dbsource", DBConfig.IP);
178
179 }
180
181 if (this.Context.Parameters.ContainsKey("user"))
182
183 {
184
185 this.Context.Parameters["user"] = DBConfig.DBUser;
186
187 }
188
189 else
190
191 {
192
193 this.Context.Parameters.Add("user", DBConfig.DBUser);
194
195 }
196
197 if (this.Context.Parameters.ContainsKey("pwd"))
198
199 {
200
201 this.Context.Parameters["pwd"] = DBConfig.DBPwd;
202
203 }
204
205 else
206
207 {
208
209 this.Context.Parameters.Add("pwd", DBConfig.DBPwd);
210
211 }
212
213 string dbname = "XXX"; // 數據庫的名稱
214
215 ExecuteSql("master", string.Format("CREATE DATABASE[{0}]", dbname)); //創建一個數據庫
216
217 string sql = LoadSqlFromAssembly("SPRC.DB.sql"); //加載這個sql腳本
218
219 ExecuteSql(dbname, sql); //運行生成數據的sql腳本.
220
221 }
222
223 }
224
上面描述了自定義安裝的初步過程.
Read Sql and Execute Sql
1
2
3private string LoadSqlFromAssembly(string Name)
4
5 {
6
7 //得到當前程序集對象
8
9 Assembly Asm = Assembly.GetExecutingAssembly();
10
11 //創建sql腳本的流對象
12
13 Stream strm = Asm.GetManifestResourceStream(Asm.GetName().Name + "." + Name);
14
15 //讀sql流對象
16
17 StreamReader reader = new StreamReader(strm);
18
19 return reader.ReadToEnd();
20
21 }
22
23
24
25 private void ExecuteSql(string DatabaseName, string Sql)
26
27 {
28
29 //創建一個數據庫連接對象
30
31 this.conn = new SqlConnection();
32
33 this.conn.ConnectionString = "user id=" + this.Context.Parameters["user"]
34
35 + ";data source=" + this.Context.Parameters["dbsource"]
36
37 + ";initial catalog=master;password=" + this.Context.Parameters["pwd"] + ";";
38
39 //創建一個sql command對象,去運行sql腳本的內容
40
41 SqlCommand command = new SqlCommand(Sql, conn);
42
43 //open數據庫的連接
44
45 command.Connection.Open();
46
47 //因為調用這個方法前,在install的方法裡面command是運行在master的庫上面的,所以需要change到當前數據庫中.
48
49 command.Connection.ChangeDatabase(DatabaseName);
50
51 try
52
53 {
54
55 //執行sql腳本,生成數據表和初始數據.
56
57 command.ExecuteNonQuery();
58
59 }
60
61 finally
62
63 {
64
65 //Finally, blocks are a great way to ensure that the connection
66
67 //is always closed.
68
69 command.Connection.Close();
70
71 }
72
73
74
75 }
76
下面描述下LoadSqlFromAssembly 和 ExecuteSql兩個方法:
自此在上面DBInstall的Project已經全部實現完畢.還需要在安裝部署中添加這個DBInstall.
創建一個Setup Project(Fileà NewàProjectàOther Project Typeà Setup and DeploymentàSetup Project,然後再剛創建號的
Setup project點擊右鍵, 點擊"添加", 選擇Project Output,在Project 選擇剛已經完成的DBInstall, 然後點擊 Primary output.
然後點擊"確定".
然後再在Setup Project上面點擊右鍵, 點擊"View"à"Custom Actions",會彈出一個窗口
然後在窗口中依次在Install, Rollback, Uninstall 三個文件夾上面創建 一個Action.
方法如下:
在文件夾上面點擊右鍵,然後點擊"Add Custom Action", 再彈出窗口裡面選擇Application Folder.
選擇剛才創建的一個DBInstall的Primary Output .
然後點擊"確定".
注意一定要在Install, Rollback, Uninstall 都添加 "Primary output from DBInstall(Active)".
只有這樣,我們在DBInstall中override的 Rollback, Uninstall才會有意義.
然後編譯setup project, 得到安裝文件,雙擊安裝.
PS: 有時候大家生成的腳本在sql裡面執行的正常, 但是在安裝過程中會出現 "Create 附近有錯誤"類似的錯誤,
請大家去掉sql文件裡面的"GO". 就可以一切正常了.
如果大家有更好的辦法, 請多多指教! 謝謝!