.NET平台下WEB应用程序的部署(安装数据库和自动配置)

来源:互联网 发布:物流仿真软件 编辑:程序博客网 时间:2024/05/16 08:54
NET平台下WEB应用程序的部署(安装数据库和自动配置)
 
李洪根
      

    在.NET平台下,部署 Web 解决方案是比较方便的。我们可以利用Visual Studio.NET 2003添加一个WEB安装项目,在部署的“文件系统编辑器”中添加项目的主输出和内容文件,非常简易地完成安装程序的制作。

       但是,这样制作的安装程序,只是将Web页和ASP.NET程序编译的DLL文件安装到目标机器的IIS目录,对于一般的应用程序是可以的(比如用Access数据库,可以一起打包到安装程序中);如果数据库是SQL SERVER,需要在部署的时候一并安装数据库,安装程序的制作就会复杂一些,需要我们自定义安装程序类。在安装程序类中执行SQL脚本并将连接字符串写入Web.config

l         安装数据库

微软MSDN上介绍过在部署应用程序的时候建立数据库。如:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxwlkWalkthroughUsingCustomActionToCreateDatabaseDuringInstallation.asp 

这种方法是创建一个安装程序类,在安装程序类中调用ADO.NET执行SQL 语句(SQL语句放在一个文本文件中)来创建数据库。

 

但是,这种方法有一个问题,如果用SQL Server2000生成了所有建表、视图、存储过程的一个脚本文件,用ADO.NET来执行这个脚本文件,就会因为脚本中有许多“GO”语句而出现错误。当然,我们可以把“GO”替换成换行符,利用ADO.NET一条条执行SQL 语句。很显然,这样的效率比较低。

 

最好的办法是调用osql执行脚本。(或者创建一个数据库项目的cmd文件,而cmd文件建立数据库的时候也是调用的osql)。

 

首先,我们新建一个ASP.NET Web应用程序,http://localhost/VbNetTest,并打开VbNetTest 项目

创建部署项目
1.         在“文件”菜单上指向“添加项目”,然后选择“新建项目”。
2.         在“添加新项目”对话框中,选择“项目类型”窗格中的“安装和部署项目”,然后选择“模板”窗格中的“Web 安装项目”。在“名称”框中键入 Test Installer。
3.         单击“确定”关闭对话框。
4.         项目被添加到解决方案资源管理器中,并且文件系统编辑器打开。
5.         在“属性”窗口中,选择 ProductName 属性,并键入 GCRM。
 
VbNetTest项目的输出添加到部署项目中
1.         在“文件系统编辑器”中,选择“Web 应用程序”文件夹。在“操作”菜单上,指向“添加”,然后选择“项目输出”。
2.         在“添加项目输出组”对话框中,选择“项目”下拉列表中的“VbNetTest”。
3.         单击“确定”关闭对话框。
4.         从列表中选择“主输出”和“内容文件”组,然后单击“确定”。
 
创建安装程序类
1.         在“文件”菜单上指向“新建”,然后选择“项目”。
2.         在“新建项目”对话框中,选择“项目类型”窗格中的“Visual Basic 项目”,然后选择“模板”窗格中的“类库”。在“名称”框中键入 DBCustomAction。
3.         单击“打开”关闭对话框。
4.         从“项目”菜单中选择“添加新项”。
5.         在“添加新项”对话框中选择“安装程序类”。在“名称”框中键入 DBCustomAction。
6.         单击“确定”关闭对话框。
 
创建自定义安装对话框
1.         在解决方案资源管理器中选择“Test Installer”项目。在“视图”菜单上指向“编辑器”,然后选择“用户界面”。
2.         在用户界面编辑器中,选择“安装”下的“启动”节点。在“操作”菜单上,选择“添加对话框”。
3.         在“添加对话框”对话框中,选择“许可协议”对话框,然后单击“确定”关闭对话框。
4.         在“添加对话框”对话框中,选择“文本框 (A)”对话框,然后单击“确定”关闭对话框。
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 和 Edit4Visible 属性,并将它们设置为 False。
创建自定义操作
1.         在解决方案资源管理器中选择“Test Installer”项目。在“视图”菜单上指向“编辑器”,然后选择“自定义操作”。
2.         在自定义操作编辑器中选择“安装”节点。在“操作”菜单上,选择“添加自定义操作”。
3.         在“选择项目中的项”对话框中,双击“应用程序文件夹”。
4.         选择“主输出来自 DBCustomAction(活动)”项,然后单击“确定”关闭对话框。
5.         在“属性”窗口中,选择 CustomActionData 属性并键入 /dbname=[CUSTOMTEXTA1] /server=[CUSTOMTEXTA2] /user=[CUSTOMTEXTA3] /pwd=[CUSTOMTEXTA4] /targetdir="[TARGETDIR]/"。
 
附/targetdir="[TARGETDIR]/"是安装后的目标路径,为了在DBCustomAction类中获得安装后的路径,我们设置此参数。
另外,安装后的路径也可以通过Reflection得到:
        Dim Asm As System.Reflection.Assembly = _
        System.Reflection.Assembly.GetExecutingAssembly
        MsgBox("Asm.Location")
添加文件
1.         将SQL Server生成的脚本文件DB.sql添加到“Test Installer”项目
2.         将安装文件LisenceFile.rtf添加到“Test Installer”项目
3.         在用户界面编辑器中,选择许可协议,设置LisenceFile属性为LisenceFile.rtf文件
 
工程中的文件 :
将代码添加到安装程序类中,DBCustomAction.vb类

Imports System.ComponentModel

Imports System.Configuration.Install

Imports System.IO

Imports System.Reflection

 

<RunInstaller(True)> Public Class DBCustomAction

    Inherits System.Configuration.Install.Installer

 

#Region "组件设计器生成的代码 "

    Public Sub New()

        MyBase.New()

        '该调用是组件设计器所必需的

        InitializeComponent()

        ' InitializeComponent() 调用之后添加任何初始化

    End Sub

    ' Installer 重写 dispose 以清理组件列表。

    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

        If disposing Then

            If Not (components Is Nothing) Then

                components.Dispose()

            End If

        End If

        MyBase.Dispose(disposing)

    End Sub

    Private components As System.ComponentModel.IContainer

    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub

#End Region

    '执行SQL 语句

    Private Sub ExecuteSql(ByVal conn As String, ByVal DatabaseName As String, ByVal Sql As String)

        Dim mySqlConnection As New SqlClient.SqlConnection(conn)

        Dim Command As New SqlClient.SqlCommand(Sql, mySqlConnection)

        Command.Connection.Open()

        Command.Connection.ChangeDatabase(DatabaseName)

        Try

            Command.ExecuteNonQuery()

        Finally

            'Close Connection

            Command.Connection.Close()

        End Try

    End Sub

    Public Overrides Sub Install(ByVal stateSaver As System.Collections.IDictionary)

        MyBase.Install(stateSaver)

        ' ------------------------建立数据库-------------------------------------------------

        Try

            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"))

            '根据输入的数据库名称建立数据库

            ExecuteSql(connStr, "master", "CREATE DATABASE " + Me.Context.Parameters.Item("dbname"))

            '调用osql执行脚本

            Dim sqlProcess As New System.Diagnostics.Process

            sqlProcess.StartInfo.FileName = "osql.exe "

            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"))

            sqlProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden

            sqlProcess.Start()

            sqlProcess.WaitForExit()  '等待执行

            sqlProcess.Close()

            '删除脚本文件

            Dim sqlFileInfo As New System.IO.FileInfo(String.Format("{0}db.sql", Me.Context.Parameters.Item("targetdir")))

            If sqlFileInfo.Exists Then

                sqlFileInfo.Delete()

            End If

        Catch ex As Exception

            Throw ex

        End Try

 

        ' ---------------------将连接字符串写入Web.config-----------------------------------

        Try

            Dim FileInfo As System.IO.FileInfo = New System.IO.FileInfo(Me.Context.Parameters.Item("targetdir") & "/web.config")

            If Not FileInfo.Exists Then

                Throw New InstallException("没有找到配置文件")

            End If

            '实例化XML文档

            Dim XmlDocument As New System.Xml.XmlDocument

            XmlDocument.Load(FileInfo.FullName)

 

            '查找到appSettings中的节点

            Dim Node As System.Xml.XmlNode

            Dim FoundIt As Boolean = False

            For Each Node In XmlDocument.Item("configuration").Item("appSettings")

                If Node.Name = "add" Then

                    If Node.Attributes.GetNamedItem("key").Value = "connString" Then

                        '写入连接字符串

                        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", _

                        Me.Context.Parameters.Item("server"), Me.Context.Parameters.Item("dbname"), Me.Context.Parameters.Item("user"), Me.Context.Parameters.Item("pwd"))

                        FoundIt = True

                    End If

                End If

            Next Node

            If Not FoundIt Then

                Throw New InstallException("web.Config 文件没有包含connString连接字符串设置")

            End If

            XmlDocument.Save(FileInfo.FullName)

        Catch ex As Exception

            Throw ex

        End Try

    End Sub

End Class

最后编译生成!
 
安装界面:
声明:本文版权与解释权归李洪根所有,如需转载,请保留完整的内容及此声明。
QQ: 21177563   MSN: lihonggen@hotmail.com
专栏:http://www.csdn.net/develop/author/netauthor/lihonggen0/

作者Blog:http://blog.csdn.net/lihonggen0/
相关文章
对该文的评论
CSDN 网友 ( 2004-10-25)
请问永c#改如何实现
dede111 ( 2004-10-18)
同样安装时出现--未将对象引用到对象实例!
why????
CSDN 网友 ( 2004-08-31)
又是编译成功了,可是安装时出现--未将对象引用到对象实例!
CSDN 网友 ( 2004-08-31)
找来找去,都没有找到CustomActionData !
CSDN 网友 ( 2004-08-31)
在“属性”窗口中,选择 CustomActionData 属性并键入 /dbname=[CUSTOMTEXTA1] /server=[CUSTOMTEXTA2] /user=[CUSTOMTEXTA3] /pwd=[CUSTOMTEXTA4] /targetdir="[TARGETDIR]/"。 

没有看到CustomActionData ??这个属性那。
///////////////
.Net的Outofmemory异常及大内存使用     选择自 RiskUO 的 Blog
关键字  .Net的Outofmemory异常及大内存使用
出处 

        从去年起我们的服务器偶尔会抛出OutOfMemoryException,即没有足够的内存继续执行程序时引发的异常。服务器内存加到4G也仍会出现该问题。软件是UO的第三方模拟器。事实上,从任务管理器里,可以看到软件占用了约1G左右的内存,当然因为GC的缘故,实际软件使用的内存在600M左右。为避免超过1G多内存的占用,并抛出Outofmemory异常,设定在内存占用到一定值时进行强制GC,一下子可以减去几百兆,但终究是没彻底解决问题。
        最近国外论坛贴了相关处理方法,在此转述一遍,希望对遇到类似问题的朋友有帮助。


对于2G内存的服务器,.Net只能使用1.2G内存。
对于4G内存的服务器,.Net可使用2.4G内存。但系统需要进行如下设置:
1、 在boot.ini文件中增加/3GB的开关。
[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(2)/WINNT
[operating systems]
multi(0)disk(0)rdisk(0)partition(2)/WINNT="????" /3GB
2、在命令行窗口,进入该目录,如 cd "C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/bin"
3、运行link命令: link -edit -LARGEADDRESSAWARE server.exe  (server.exe为你的.Net程序)
4、你的server.exe就可以使用到2.4G内存了


//////////////////////////////////////

.net安装程序部署SQL Server数据库     选择自 younther 的 Blog
关键字  部署 安装
出处 

目录

l 摘要
l 一般安装程序的制作
l 在安装程序中部署SQL Server数据库
1. 通过调用osql来执行数据库脚本文件
2. 通过把脚本文件作为资源文件载入
3. 通过sp_attach_db来创建数据库
l 总结

摘要
一个项目完成之后,安装程序的制作是一个必要的过程。如果需要部署数据库,则使安装程度的制作变得比较麻烦。使用visual studio.net可以非常方便的制作应用程序以及部署程序中需要的数据库。本文介绍了如何使用visual studio.net制作安装程序,以及如何在安装程序中部署数据库.本文假设您对ADO.net比较熟悉。

1.一般安装程序的制作

     Visual studio.net 提供了很强大并且非常便捷的安装程序制作功能。一般的安装程序制作可以参考如下步骤:
(1) 在Visual studio.net里面新建一个安装项目(针对一般windows应用程序)或者web安装项目(针对基于web的应用程序),比如叫SetupFace.
(2) 在解决方案里面的项目中的SetupFace上单击右键,可以看到如下的视图:
 
图1 安装程序中的视图
           视图中出现的项目就是在制作安装程序中需要涉及到的项目。
a. 文件系统部分提供了如何把需要安装到目标机可执行程序以及运行时需要的dll等打包到安装程序中,同时也提供了如何在目标机的桌面上和程序菜单中创建快捷方式以及文件夹等。
b. 注册表部分提供了如何在目标机的注册表中添加相关的键值。
c. 文件类型提供了在目标机上创建一个文件类型与应用程序的关联,并可以为注册的文件类型增加相关的右键菜单功能。比如注册一个.pdf的文件,使用你自己的程序打开。
d. 用户界面提供了在安装过程中的界面,也可以根据自己的需要创建如自述文件,注册码校验等等功能。创建项目时已经提供了一些基本的画面。
e. 自定义操作部分主要提供了如何在安装的不同阶段中完成不同的工作。比如在安装过程中创建数据库,在卸载过程中删除数据库等。
f. 启动条件部分提供了在安装您的应用程序前需要完成什么条件。Visual studio.net提供了可以在用户计算机上搜索启动条件的功能。比如要求某个程序已经安装,可以通过搜索文件系统或则搜索注册表来完成。
(3)  在视图中选择文件系统,将看到如下画面:
 
图2 文件系统界面
         如果您需要完成一个简单的安装程序,在添加中选择文件,选择您以及编译完成的应用程序,Visual studio.net会自动引入该应用程序所需要的dll(只针对Visual studio.net开发的应用程序,其他的程序没有试过),然后根据您的需要在用户的”程序”菜单和用户桌面创建快捷方式,然后把快捷方式的指向选择为在应用程序文件夹中导入的应用程序即可。
(4) 最后,可以直接编译该项目,安装程序的制作即可完成。
如果需要更多的控制和修改安装程序过程中的内容,可以根据第(2)步中提到的不同视图进行编辑即可。如果需要制作web项目的安装程序,在创建项目时选择创建Web项目即可, 其他部分大同小异。也可以直接参考MSDN的如下链接:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxconATourOfVisualStudio.asp

2.在安装程序中部署SQL Server数据库

通过上面的介绍,一般应用程序的制作非常容易,基本上就是把您的应用程序拖入该安装程序的过程。如果您的应用程序的运行需要数据库的支持(如SQL Server),问题就变得比较复杂一点。
主要有如下几个方面的问题:
(1) 如何在获得安装画面的值,比如获得用户输入的用户名密码。
(2) 如何设计一个程序来与数据库服务器进行交互,创建新的数据库。
如何在获得安装程序中的值,可以参看如下链接,这里我们不做太多的介绍。
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxconATourOfVisualStudio.asp>
这个例子演示了如何在用户界面自定义对话框要求用户输入信息,然后在自定义操作中把获得的值通过CustomActionData来传递给自定义操作中的主输出,最后在主输出相面里面的程序里面来创建一个数据库。
通过对上面的例子的理解,基本上可以按照这个方式来创建一个数据库,它通过ADO.net执行SQL语句来完成创建数据库的。但是,如果有大量的数据表以及存储过程需要建立,通过这个的方式非常麻烦。可不可以通过直接在SQL Server中创建相应的数据库生成脚本文件来直接完成呢?
我们有3个解决方案:
(1) 通过调用osql来执行数据库脚本文件
(2) 通过把相应的脚本文件作为资源文件嵌入到项目中,然后通过ADO.net来执行
(3) 通过调用SQL Server的sp_attach_db的存储过程来直接附加数据库。

2.1 通过调用osql来执行数据库脚本文件

    从上面的例子我们已经知道了如何传递值,那么我们只要在项目文件中程序段中执行osql即可。
这里有一个问题就是从什么地方找到数据库的脚本文件。我们可以把脚本文件放到文件系统中,直接安装到用户机器上,并可以通过如下方法获得到该文件的位置。
  Assembly asm=Assembly.GetExecutingAssembly();
  String setuppath=asm.Location;
这样我们就可以知道脚本文件的位置了,下面的文件就是如何启动osql程序了。我们可以通过如下的代码段来完成:
   Process sqlprocess=new Process();     sqlprocess.StartInfo.FileName="osql.exe";
 sqlprocess.StartInfo.Arguments=String.Format("-U {0} -P {1} -S {2} -i {3}",this.uid,this.pwd,this.serverip,this.spath);  //uid 为用户名,pwd为密码,serverip为目标服务器的ip,spath为数据库脚本所在的路径
     sqlprocess.StartInfo.WindowStyle=ProcessWindowStyle.Hidden;
 sqlprocess.Start();
 sqlprocess.WaitForExit();  //等待程序执行
 sqlprocess.Close();
    
从上面可以知道,该方法必须要求安装程序的客户机以及安装好了SQL Server才能使用(osql为安装了SQL Server后提供的命令行下的程序).同时在实际的测试过程中,我们发现如果对于用户在安装程序是选择带有空格的路径,如;C:/program files/yourappliaction/时,安装失败。这个是一个比较严重的问题。

2.2 通过把脚本文件作为资源文件载入

    从前面的讨论中我们可以看到,直接使用ADO.net执行时比较麻烦,需要一句句执行,如果使用脚本,数据库中生成的脚本中有”GO”命令,在ADO.net中执行时会出问题。因此,根据对数据库安装脚本的分析,我们可以采用如下替代方案。
在数据库的安装过程中,无外乎如下几个部分:
(1) 创建数据库
(2) 创建表
(3) 创建试图或者存储过程
并且这三个部分是有先后顺序的,顺序不能颠倒,但是每个过程中没有顺序关系。在测试过程中我们发现可以在一条语句中创建多个表或者多个存储过程。也就是说,我们可以把执行过程按照上面的顺序执行就行了。并且我们把数据库脚本作为资源文件嵌入,只要调入执行就可以了,这样就达到了简化创建一条条命令的过程。
获得资源文件代码如下:
Assembly Asm=Assembly.GetExecutingAssembly();
StreamReader str;
str=new StreamReader(Asm.GetManifestResourceStream(Asm.GetName().Name+"."+filename))// filename为你需要摘入的资源文件。作为资源文件时,只要把文件导入到您的项目中,并且把生成操作改为嵌入的资源即可。
这里我们是直接获得了该文件的文件流,因此直接把该流中的内容读入即可。
我们可以通过如下操作完成:
(1) 建立一个数据库的链接,创建数据库. 比如: connectionstring=”server=127.0.0.1,uid=sa,pwd=pwd”;
(2) 重新创建一个数据库链接,该链接指向创建的数据库。connectionstring=”server=127.0.0.1,uid=sa,pwd=pwd,database=yourdatabase”;
(3) 在新的链接中执行创建数据表和数据存储过程的代码即可。

需要注意的是:不要在你的脚本中有GO命名,其他命令都可以直接执行。
该方法的好处在于: 可以不要求安装的目标机上有SQL Server,也不存在因为文件路径中有空格的问题而倒是安装程序失败。当然,如果您的数据库为Oracle或者DB2等,您也可以采用类似的方法来实现。

2.3 通过sp_attach_db来创建数据库

通过上面的讨论我们已经很清楚如何安装数据库了。在安装数据库的过程中,我们除了可以通过数据库脚本来创建数据库之外,我们也可以通过SQL Server的系统存储过程sp_attach_db来附加数据库。
这里我们解决两个问题即可:
(1) 确定数据库文件(.mdf和.ldf)的位置。
(2) 执行存储过程。

对于问题1我们可以借鉴安装数据的第一种方法,即把.mdf和.ldf通过文件系统安装到目标机上,然后通过
     Assembly asm=Assembly.GetExecutingAssembly();
  String setuppath=asm.Location;
获得文件的路径。

最后通过调用sp_attach_db 加上相应的参数即可完成。
需要注意的是: 该方法也只能针对数据库安装在本机的情况下进行安装。

总结

本文通过介绍了三种不同的方法来在安装程序是如何安装数据库,同时也分析了不同的方法的优劣之处,用户可以根据自己的实际需要来选择安装方法。同时,通过该方法的提出,用户也可以完成在安装程序是对数据库的配置工作。

 


相关文章
对该文的评论
starcraft501 ( 2004-10-18)

请详细解释一下如何获得文件的路径。

最后通过调用sp_attach_db 加上相应的参数即可完成。

相应的参数需要设置 安装文件的路径+安装文件名

照作者的方法好像不行,请解决,万分感谢!

原创粉丝点击