借鉴MSDN webcasts的
Asp.net程序部署和
李洪根的一篇文章,然后加上自己的亲身体会,把整个SQL和Asp.net(vb.net)一起打包的全过程写一下。
一.准备必要的文件
1. SQL脚本文件,生成以后安装过程中需要的表和存储过程等等;
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/生成脚本.gif)
生成之后,就暂时把它命名为db.sql(注意大小写)
2.LisenceFile.rtf的安装文件,因为我的系统是个人的,而且free的,所以就没有做。这个以后也是要用到的。
二.在自己现有的项目里面创建部署项目:
1. 在“文件”菜单上指向“添加项目”,然后选择“新建项目”。(图1-2)
2. 在“添加新项目”对话框中,选择“项目类型”窗格中的“安装和部署项目”,然后选择“模板”窗格中的“Web 安装项目”。在“名称”框中键入 Test Installer。(图1-3)
3. 单击“确定”关闭对话框。
4. 项目被添加到解决方案资源管理器中,并且文件系统编辑器打开。
5. 在“属性”窗口中,选择 ProductName 属性,并键入 GCRM。
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/新建项目.gif)
(1-2)
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/Web%20安装项目.gif)
(图1-3)其他项目的作用可以参考Webcast
三。将 VbNetTest项目的输出添加到部署项目中(假如你的虚拟目录是SQLANDASPNet)
1. 在“文件系统编辑器”中,选择“Web 应用程序文件夹"。在“操作”菜单上,指向“添加”,然后选择“项目输出”。(图1-4)
2. 在“添加项目输出组”对话框中,选择“项目”下拉列表中的“SQLANDASPNet”。
3. 单击“确定”关闭对话框。
4. 从列表中选择“主输出”和“内容文件”组,然后单击“确定”。(图1-5)
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/项目输出.gif)
(图1-4)
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/添加项目输出1.gif)
(图1-5)其他的作用可以参考webcast,源文件就是所有项目的的文件
四.
创建自定义安装对话框
1. 在解决方案资源管理器中选择“Test Installer”项目。在“视图”菜单上指向“编辑器”,然后选择“用户界面”。 (图1-6)
2. 在用户界面编辑器中,选择“安装”下的“启动”节点。在“操作”菜单上,选择“添加对话框”。
3. 在“添加对话框”对话框中,选择“许可协议”对话框,然后单击“确定”关闭对话框。 (注:我没有添加,因为暂时我还是不需要,需要的要添加一下哦)
4. 在“添加对话框”对话框中,选择“文本框 (A)”对话框,然后单击“确定”关闭对话框。 (图1-7)
5. 在“操作”菜单上,选择“上移”。重复此步骤,直到“文本框 (A)”对话框位于“安装文件夹”节点之上。
6. 在“属性”窗口中,选择 BannerText 属性并键入:安装数据库.。
7. 选择 BodyText 属性并键入:安装程序将在目标机器上安装数据库。
8. 选择 Edit1Label 属性并键入:数据库名称:。
9. 选择 Edit1Property 属性并键入 CUSTOMTEXTA1。
10. 选择 Edit1Value 属性并键入:GsCrm。
11. 选择 Edit2Label 属性并键入:服务器名:。
12. 选择 Edit2Property 属性并键入 CUSTOMTEXTA2。
13. 选择 Edit2Value 属性并键入:(local)。
14. 选择 Edit3Label 属性并键入:用户名:。
15. 选择 Edit3Value 属性并键入:sa。
16. 选择 Edit3Property 属性并键入 CUSTOMTEXTA3。
17. 选择 Edit4Label 属性并键入:密码:。
18. 选择 Edit4Property 属性并键入 CUSTOMTEXTA4。
19. 选择 Edit2Visible、Edit3Visible ,并将它们设置为 False。(图1-8)
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/添加安装界面.gif)
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/添加文本对话框.gif)
(图1-7)
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/文本对话框.gif)
(图1-8)
(五).创建自定义操作
1. 在解决方案资源管理器中选择“Test Installer”项目。在“视图”菜单上指向“编辑器”,然后选择“自定义操作”。(图1-9)
2. 在自定义操作编辑器中选择“安装”节点。在“操作”菜单上,选择“添加自定义操作”。
3. 在“选择项目中的项”对话框中,双击“应用程序文件夹”。
4. 选择“主输出来自 DBCustomAction(活动)”项,然后单击“确定”关闭对话框。
5. 在“属性”窗口中,选择 CustomActionData 属性并键入 /dbname=[CUSTOMTEXTA1] /server=[CUSTOMTEXTA2] /user=[CUSTOMTEXTA3] /pwd=[CUSTOMTEXTA4] /targetdir="[TARGETDIR]\"。 (图1-10)
附/targetdir="[targetdir]\"是安装后的目标路径,为了在dbcustomaction类中获得安装后的路径,我们设置此参数。
另外,安装后的路径也可以通过Reflection得到:
Dim Asm As System.Reflection.Assembly = _
System.Reflection.Assembly.GetExecutingAssembly
MsgBox("Asm.Location")
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/自定义操作.gif)
(图1-9)
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/自定义操作1.gif)
(图1-10)
呵呵,已经好多了,剩下来的是关键性步骤,我花了好多时间研究。
(六)创建安装程序类
1. 在“文件”菜单上指向“新建”,然后选择“项目”。
2. 在“新建项目”对话框中,选择“项目类型”窗格中的“Visual Basic 项目”,然后选择“模板”窗格中的“类库”。在“名称”框中键入 DBCustomAction。
3. 单击“打开”关闭对话框。
4. 从“项目”菜单中选择“添加新项”。
5. 在“添加新项”对话框中选择“安装程序类”。在“名称”框中键入 DBCustomAction。
6. 单击“确定”关闭对话框。(图1-11,1-12)
注:这里是在原来的项目上建立一个简单的安装文件就可以了。
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/添加安装程序类.gif)
(图1-11)
添加后的效果图:
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/安装程序类.gif)
(图1-12)这里的sql文件是要等一下添加的
(七)
添加文件
1. 将SQL Server生成的脚本文件db.sql添加到“Test Installer”项目(图1-12)
2. 将安装文件LisenceFile.rtf添加到“Test Installer”项目
3. 在用户界面编辑器中,选择许可协议,设置LisenceFile属性为LisenceFile.rtf文件
(八)
一下的代码是整个部署的最重要的一部分了
将代码添加到安装程序类中,dbcustomaction.vb类
1
Imports System.ComponentModel
2![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/None.gif)
3
imports System.Configuration.Install
4![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/None.gif)
5
imports System.IO
6![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/None.gif)
7
imports System.Reflection
8![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/None.gif)
9
10![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/None.gif)
11![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
<runinstaller(true)> Public Class DBCustomActionClass DBCustomAction
12![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
inherits System.Configuration.Install.Installer
14![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
16![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
组件设计器生成的代码#region "组件设计器生成的代码 "
18![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Sub New()Sub New()
20![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
mybase.new()
22![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
'该调用是组件设计器所必需的
24![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
initializecomponent()
26![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
'在 InitializeComponent() 调用之后添加任何初始化
28![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29
end Sub
30![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31
' Installer 重写 dispose 以清理组件列表。
32![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
protected Overloads Overrides Sub Dispose()Sub Dispose(ByVal disposing As Boolean)
34![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35
if disposing Then
36![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
37
if Not (components Is Nothing) Then
38![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
39
components.dispose()
40![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
41
end If
42![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
43
end If
44![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
45
mybase.dispose(disposing)
46![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
47
end Sub
48![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
49
private components As System.ComponentModel.IContainer
50![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
51![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
<system.diagnostics.debuggerstepthrough()> Private Sub InitializeComponent()Sub InitializeComponent()
52![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
53
end Sub
54![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
55
#end Region
56![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
57
'执行sql 语句
58![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
59![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private Sub ExecuteSql()Sub ExecuteSql(ByVal conn As String, ByVal DatabaseName As String, ByVal Sql As String)
60![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
61
dim mySqlConnection As New SqlClient.SqlConnection(conn)
62![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
63
dim Command As New SqlClient.SqlCommand(Sql, mySqlConnection)
64![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
65
command.connection.open()
66![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
67
command.connection.changedatabase(databasename)
68![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
69
try
70![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
71
command.executenonquery()
72![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
73
finally
74![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
75
'close Connection
76![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
77
command.connection.close()
78![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
79
end Try
80![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
81
end Sub
82![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
83![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Overrides Sub Install()Sub Install(ByVal stateSaver As System.Collections.IDictionary)
84
MyBase.Install(stateSaver)
85![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
86
' ------------------------建立数据库-------------------------------------------------
87![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
88
try
89![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
90
dim connStr As String = String.Format("data source={0};user id={1};password={2};persist security info=false;packet size=4096", Me.Context.Parameters.Item("server"), Me.Context.Parameters.Item("user"), Me.Context.Parameters.Item("pwd"))
91![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
92
'根据输入的数据库名称建立数据库
93![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
94
executesql(connstr, "master", "CREATE DATABASE " + Me.Context.Parameters.Item("dbname"))
95![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
96
'调用osql执行脚本
97![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
98
dim sqlProcess As New System.Diagnostics.Process
99![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
100
sqlprocess.startinfo.filename = "osql.exe "
101![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
102
sqlprocess.startinfo.arguments = String.Format(" -U {0} -P {1} -d {2} -i {3}db.sql", Me.Context.Parameters.Item("user"), Me.Context.Parameters.Item("pwd"), Me.Context.Parameters.Item("dbname"), Me.Context.Parameters.Item("targetdir"))
103![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
104
sqlprocess.startinfo.windowstyle = ProcessWindowStyle.Hidden
105![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
106
sqlprocess.start()
107![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
108
sqlprocess.waitforexit() '等待执行
109![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
110
sqlprocess.close()
111![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
112
'删除脚本文件
113![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
114
dim sqlFileInfo As New System.IO.FileInfo(String.Format("{0}db.sql", Me.Context.Parameters.Item("targetdir")))
115![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
116
if sqlFileInfo.Exists Then
117![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
118
sqlfileinfo.delete()
119![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
120
end If
121![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
122
catch ex As Exception
123![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
124
throw ex
125![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
126
end Try
127![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
128
129![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
130
' ---------------------将连接字符串写入Web.config-----------------------------------
131![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
132
try
133![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
134
dim FileInfo As System.IO.FileInfo = New System.IO.FileInfo(Me.Context.Parameters.Item("targetdir") & "\web.config")
135![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
136
if Not FileInfo.Exists Then
137![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
138
throw New InstallException("没有找到配置文件")
139![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
140
end If
141![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
142
'实例化xml文档
143![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
144
dim XmlDocument As New System.Xml.XmlDocument
145![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
146
xmldocument.load(fileinfo.fullname)
147![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
148
149![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
150
'查找到appsettings中的节点
151![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
152
dim Node As System.Xml.XmlNode
153![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
154
dim FoundIt As Boolean = False
155![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
156
for Each Node In XmlDocument.Item("configuration").Item("appSettings")
157![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
158
if Node.Name = "add" Then
159![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
160
if Node.Attributes.GetNamedItem("key").Value = "connString" Then
161![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
162
'写入连接字符串
163![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
164
node.attributes.getnameditem("value").value = String.Format("Persist Security Info=False;Data Source={0};Initial Catalog={1};User ID={2};Password={3};Packet Size=4096;Pooling=true;Max Pool Size=100;Min Pool Size=1", _
165![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
166
me.context.parameters.item("server"), Me.Context.Parameters.Item("dbname"), Me.Context.Parameters.Item("user"), Me.Context.Parameters.Item("pwd"))
167![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
168
foundit = True
169![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
170
end If
171![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
172
end If
173![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
174
next Node
175![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
176
if Not FoundIt Then
177![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
178
throw New InstallException("web.Config 文件没有包含connString连接字符串设置")
179![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
180
end If
181![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
182
xmldocument.save(fileinfo.fullname)
183![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
184
catch ex As Exception
185![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
186
throw ex
187![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
188
end Try
189![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
190
end Sub
191![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
192
end Class
193![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/None.gif)
194![](https://xucanzhao.cnblogs.com/Images/OutliningIndicators/None.gif)
有点难度的就是那个Process类,它调用了osql.exe程序,来执行sql语句osql -U,-P,,-d,-i。
web.config的修改代码是利用xml的语法实现。不是很难理解。
最后编译生成!如图:
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/生成.gif)
安装界面:如图
![](https://xucanzhao.cnblogs.com/images/cnblogs_com/xucanzhao/Asp.net部署/安装.gif)
哈哈,总算写完了,也不知道有没有写好
。
最后还是感谢李洪根老师和微软的讲师。结合他们的共同的经验,部署起来真的很简单。