怎样在打包程序中自动安装SQL Server数据库?
1、创建安装项目“Setup1”安装项目
在“文件”菜单上指向“添加项目”,然后选择“新建项目”。
在“添加新项目”对话框中,选择“项目类型”窗格中的“安装和部署项目”,然后选择“模板”窗格中的“安装项目”。在“名称”框中键入 “setup1”。
单击“确定”关闭对话框。
项目被添加到解决方案资源管理器中,并且文件系统编辑器打开。
在“属性”窗口中,选择 ProductName 属性,并键入”亿万电器成套报价系统”。
2、在安装项目中创建安装程序类(install.cs)。
添加创建数据库(InstallDatabase.txt)、删除数据库(DropDatabase.txt)、初始化数据基本数据(InitializeData.txt)脚本文件,将属性“生成操作”设为“嵌入的资源”。代码如下:
1
using System;
2![]()
3
using System.Collections;
4![]()
5
using System.ComponentModel;
6![]()
7
using System.Configuration.Install;
8![]()
9
using System.Data;
10![]()
11
using System.Data.SqlClient;
12![]()
13
using System.IO;
14![]()
15
using System.Reflection;
16![]()
17
using System.Text.RegularExpressions;
18![]()
19
using System.Windows.Forms;
20![]()
21
using System.Text;
22![]()
23
using Microsoft.Win32;
24![]()
25
26![]()
27
namespace install
28![]()
29![]()
![]()
{
30![]()
31![]()
/**//// <summary>
32![]()
33
/// Installer 的摘要说明。
34![]()
35
/// </summary>
36![]()
37
[RunInstaller(true)]
38![]()
39
public class Installer : System.Configuration.Install.Installer
40![]()
41![]()
{
42![]()
43![]()
/**//// <summary>
44![]()
45
/// 必需的设计器变量。
46![]()
47
/// </summary>
48![]()
49
string conStr="packet size=4096;integrated security=SSPI;"+
50![]()
51
"data source=\"(local)\";persist security info=False;"+
52![]()
53
"initial catalog=master;connect timeout=300";
54![]()
55
RijndaelCryptography rijndael = new RijndaelCryptography();
56![]()
57
private System.ComponentModel.Container components = null;
58![]()
59
60![]()
61
public Installer()
62![]()
63![]()
{
64![]()
65
// 该调用是设计器所必需的。
66![]()
67
InitializeComponent();
68![]()
69
70![]()
71
// TODO: 在 InitializeComponent 调用后添加任何初始化
72![]()
73
}
74![]()
75
76![]()
77![]()
/**//// <summary>
78![]()
79
/// 清理所有正在使用的资源。
80![]()
81
/// </summary>
82![]()
83
protected override void Dispose( bool disposing )
84![]()
85![]()
{
86![]()
87
if( disposing )
88![]()
89![]()
{
90![]()
91
if(components != null)
92![]()
93![]()
{
94![]()
95
components.Dispose();
96![]()
97
}
98![]()
99
}
100![]()
101
base.Dispose( disposing );
102![]()
103
}
104![]()
105
106![]()
107![]()
组件设计器生成的代码#region 组件设计器生成的代码
108![]()
109![]()
/**//// <summary>
110![]()
111
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
112![]()
113
/// 此方法的内容。
114![]()
115
/// </summary>
116![]()
117
private void InitializeComponent()
118![]()
119![]()
{
120![]()
121
components = new System.ComponentModel.Container();
122![]()
123
}
124![]()
125
#endregion
126![]()
127
128![]()
129![]()
重载自定义安装方法#region 重载自定义安装方法
130![]()
131
protected override void OnBeforeInstall(IDictionary savedState)
132![]()
133![]()
{
134![]()
135
base.OnBeforeInstall (savedState);
136![]()
137
}
138![]()
139
public override void Install(IDictionary stateSaver)
140![]()
141![]()
{
142![]()
143
base.Install (stateSaver);
144![]()
145
string databaseServer = Context.Parameters["server"].ToString();
146![]()
147
string userName = Context.Parameters["user"].ToString();
148![]()
149
string userPass = Context.Parameters["pwd"].ToString();
150![]()
151
string targetdir = this.Context.Parameters["targetdir"].ToString();
152![]()
153
154![]()
155
conStr = GetLogin(databaseServer,userName,userPass,"master");
156![]()
157
SqlConnection sqlCon = new SqlConnection();
158![]()
159
160![]()
161
try
162![]()
163![]()
{
164![]()
165
166![]()
167
sqlCon.ConnectionString = conStr;
168![]()
169
sqlCon.Open();
170![]()
171
172![]()
173
rijndael.GenKey();
174![]()
175
rijndael.Encrypt(conStr);
176![]()
177
178![]()
179
stateSaver.Add("key",rijndael.Key);
180![]()
181
stateSaver.Add("IV",rijndael.IV);
182![]()
183
stateSaver.Add("conStr",rijndael.Encrypted);
184![]()
185
186![]()
187
ExecuteSql(sqlCon,"InstallDatabase.txt");
188![]()
189
ExecuteSql(sqlCon,"InitializeData.txt");
190![]()
191
192![]()
193
if(sqlCon.State!=ConnectionState.Closed)sqlCon.Close();
194![]()
195
}
196![]()
197
catch(SqlException)
198![]()
199![]()
{
200![]()
201
MessageBox.Show("安装失败!\n数据库配置有误,请正确配置信息!","错误",MessageBoxButtons.OK,MessageBoxIcon.Error);
202![]()
203
if(sqlCon.State!=ConnectionState.Closed) sqlCon.Close();
204![]()
205
this.Rollback(stateSaver);
206![]()
207
}
208![]()
209
210![]()
211
}
212![]()
213
protected override void OnAfterInstall(IDictionary savedState)
214![]()
215![]()
{
216![]()
217
base.OnAfterInstall(savedState);
218![]()
219
}
220![]()
221
222![]()
223
public override void Rollback(IDictionary savedState)
224![]()
225![]()
{
226![]()
227
base.Rollback (savedState);
228![]()
229
}
230![]()
231
public override void Uninstall(IDictionary savedState)
232![]()
233![]()
{
234![]()
235
base.Uninstall (savedState);
236![]()
237
if(savedState.Contains("conStr"))
238![]()
239![]()
{
240![]()
241
string targetdir = this.Context.Parameters["targetdir"].ToString();
242![]()
243
RijndaelCryptography rijndael = new RijndaelCryptography();
244![]()
245
rijndael.Key = (byte[])savedState["key"];
246![]()
247
rijndael.IV = (byte[])savedState["IV"];
248![]()
249
conStr = rijndael.Decrypt((byte[])savedState["conStr"]);
250![]()
251
SqlConnection sqlCon = new SqlConnection(conStr);
252![]()
253
ExecuteDrop(sqlCon);
254![]()
255
}
256![]()
257
}
258![]()
259
#endregion
260![]()
261
262![]()
263![]()
数据操作方法#region 数据操作方法
264![]()
265
//从资源文件获取中数据执行脚本
266![]()
267
private static string GetScript(string name)
268![]()
269![]()
{
270![]()
271
Assembly asm = Assembly.GetExecutingAssembly();
272![]()
273
Stream str = asm.GetManifestResourceStream(asm.GetName().Name+ "." + name);
274![]()
275
StreamReader reader = new StreamReader(str,System.Text.Encoding.Default);
276![]()
277
System.Text.StringBuilder output = new System.Text.StringBuilder();
278![]()
279
string line = "";
280![]()
281
while((line = reader.ReadLine())!=null)
282![]()
283![]()
{
284![]()
285
output.Append(line + "\n");
286![]()
287
}
288![]()
289
return output.ToString();
290![]()
291
292![]()
293
}
294![]()
295
//获取数据库登录连接字符串
296![]()
297
private static string GetLogin(string databaseServer,string userName,string userPass,string database)
298![]()
299![]()
{
300![]()
301
return "server=" + databaseServer + ";database="+database+";User ID=" + userName + ";Password=" + userPass +";connect timeout=300;";
302![]()
303
}
304![]()
305
//执行数据库脚本方法
306![]()
307
private static void ExecuteSql(SqlConnection sqlCon,string sqlfile)
308![]()
309![]()
{
310![]()
311
string[] SqlLine;
312![]()
313
Regex regex = new Regex("^GO",RegexOptions.IgnoreCase | RegexOptions.Multiline);
314![]()
315
316![]()
317
string txtSQL = GetScript(sqlfile);
318![]()
319
SqlLine = regex.Split(txtSQL);
320![]()
321
322![]()
323
if(sqlCon.State!=ConnectionState.Closed)sqlCon.Close();
324![]()
325
sqlCon.Open();
326![]()
327
328![]()
329
SqlCommand cmd = sqlCon.CreateCommand();
330![]()
331
cmd.Connection = sqlCon;
332![]()
333
334![]()
335
foreach(string line in SqlLine)
336![]()
337![]()
{
338![]()
339
if(line.Length>0)
340![]()
341![]()
{
342![]()
343
cmd.CommandText = line;
344![]()
345
cmd.CommandType = CommandType.Text;
346![]()
347
try
348![]()
349![]()
{
350![]()
351
cmd.ExecuteNonQuery();
352![]()
353
}
354![]()
355
catch(SqlException ex)
356![]()
357![]()
{
358![]()
359
//rollback
360![]()
361
string ss = ex.Message;
362![]()
363
ExecuteDrop(sqlCon);
364![]()
365
break;
366![]()
367
}
368![]()
369
}
370![]()
371
}
372![]()
373
}
374![]()
375
//删除数据库
376![]()
377
private static void ExecuteDrop(SqlConnection sqlCon)
378![]()
379![]()
{
380![]()
381
if(sqlCon.State!=ConnectionState.Closed)sqlCon.Close();
382![]()
383
sqlCon.Open();
384![]()
385
SqlCommand cmd = sqlCon.CreateCommand();
386![]()
387
cmd.Connection = sqlCon;
388![]()
389
cmd.CommandText = GetScript("DropDatabase.txt");
390![]()
391
cmd.CommandType = CommandType.Text;
392![]()
393
cmd.ExecuteNonQuery();
394![]()
395
sqlCon.Close();
396![]()
397
}
398![]()
399
#endregion
400![]()
401
}
402![]()
403![]()
单击“生成”菜单下“生成解决方案”,生成install.dll安装类文件。
3、将“主程序”项目的输出添加到部署项目中
在“文件系统编辑器”中,选择“应用程序文件夹”,单击右键指向“添加”,添加“项目输出”。
在“添加项目输出组”对话框中,选择“项目”下拉表框中选择你的主安装程序类,如上面的“install”。
从列表框中选择“主输出”组,然后单击“确定”关闭。
4、创建自定义安装对话框
在解决方案资源管理器中选择安装项目“Setup1”项目,在“视图”菜单上指向“编辑器”,然后选择“用户界面”。
在用户界面编辑器具中,选择“安装”下的“启动”节点。在“操作”菜单上,选择“添加对话框”。
在“添加对话框”中选择“文本框(A)”对话框,然后单击“确定”关闭对话框。
在“操作”菜单上,选择“上移”,重复此步骤,移到“安装文件夹”上。
在“文本框(A)”上单击“属性窗口”,设置如下图所示:
![]()
5、建自定义操作
在解决方案资源管理器中选择安装项目“Setup1”项目,在“视图”菜单上指向“编辑器”,然后选择“自定义操作”。
在“自定义操作编辑器”中选择“安装”节点。单击右键“添加自定义操作”,在选择项目中的项中选择“应用程序文件夹”,选择“主输出来自install(活动)”。
在“属性窗口”中选择“CustomActionData”属性并键入“/server=[EDITA1] /user=[EDITA2] /pwd=[EDITA3] /targetdir="[TARGETDIR]\"”。
附:/targetdir="[TARGETDIR]\"是安装后的目标路径,为了在install类中获得安装后的路径,我们设置此参数。
单击“生成”菜单下的“生成解决方案”,编译安装项目。