本文原创,转载请注明出处
最近临时搞了个办证中心的小东东(我现在公司就是搞办证中心网站及软件的),开发完了得找人过去安装或是把网站文件什么的打包发给对方安装。项目分网站文件及SQL数据两部门,也就是说在部署的时候得同时安装网站文件及在SQL数据库中建好相关表、视图等内容。
我使用了VS2005中的安装和部署项目中的“Web安装项目”,大概使用了下发现部署网站相当方便,但部署SQL数据就得在原基础上进行自定义操作了。这东东以前没搞过,比较没有头绪,找了不少资料:
带SQL数据库操作的安装部署视频教程
视频教程带的原码(里面少个WEB项目,想研究的自己添加个WEB项目,然后里面随便加个页面就行了)
视频教程带的PDF
视频教程带的QA
上面的教程看过后基本就对安装部署的自定义操作比较了解了,然后就可以按以上示例进行动手操作了。
我在网上找到的比值得参考的一个全程教学:
如何用VS2005制作Web安装程序 -徐智雄的BLOG(附带:
用VS2005制作网页对IIS进行操作),这里写的更详细点,我这里也就偷偷懒不把全程写一回了,把一些值得注意的地方写下
1、在绑定自定义安装对话框中参数时,如下图所示的地方:
注意:
- /DBServer="[DBSERVER]" /DBName="[DBNAME]" /UserName="[DBUSERNAME]" /Password="[DBPASSWORD]" /targetdir="[TARGETDIR]\"
/DBServer="[DBSERVER]" /DBName="[DBNAME]" /UserName="[DBUSERNAME]" /Password="[DBPASSWORD]" /targetdir="[TARGETDIR]\"
每个参数之间得有
空格,/targetdir="[TARGETDIR]\"到时候得到的为当前安装路径字串并在最后面添加一个"\",当然也可以直接中/targetdir="[TARGETDIR]"。在写这些参数的时候推荐以
/DBServer="[DBSERVER]"这种格式,上面的教程都省略写成/DBServer=[DBSERVER]
2、执行SQL语句时那个SQL.TXT要注意的地方
注意:SQL.TXT(可以是其它文件名)的编码要为Unicode,文件中不要包含"GO",如果视图等内容要求必须是批查询中的第一条语句的SQL语句得用EXEC('语句内容')来处理,要不会报错的。如:
- exec('
- CREATE TABLE [dbo].[py_Resume] (
- [R_ID] [int] IDENTITY (1, 1) NOT NULL ,
- [R_Content] [ntext] COLLATE Chinese_PRC_CI_AS NOT NULL ,
- [R_DateTime] [datetime] NULL ,
- [C_ID] [int] NOT NULL
- ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
-
- CREATE TABLE [dbo].[py_photo] (
- [PhotoID] [int] IDENTITY (1, 1) NOT NULL ,
- [WorkersID] [nvarchar] (4) COLLATE Chinese_PRC_CI_AS NOT NULL ,
- [PhotoPath] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL
- ) ON [PRIMARY]
- ')
exec('
CREATE TABLE [dbo].[py_Resume] (
[R_ID] [int] IDENTITY (1, 1) NOT NULL ,
[R_Content] [ntext] COLLATE Chinese_PRC_CI_AS NOT NULL ,
[R_DateTime] [datetime] NULL ,
[C_ID] [int] NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE TABLE [dbo].[py_photo] (
[PhotoID] [int] IDENTITY (1, 1) NOT NULL ,
[WorkersID] [nvarchar] (4) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[PhotoPath] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
')
我折腾了不少时间才执行成功的SQL(大家好参考下)
如果想在类似查询分析器那里比较方便的进行执行SQL的话可以参考以下代码段,这个我没试过,是调用osql.exe来执行SQL的,应该不会有像SqlCommand执行的问题了
- 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"))
-
- dim sqlProcess As New System.Diagnostics.Process
- sqlprocess.start
- info.filename = "osql.exe "
- sqlprocess.start
- info.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.start
- info.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
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.start
info.filename = "osql.exe "
sqlprocess.start
info.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.start
info.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
3、关于调试的问题
这个问题我找了很久不知道怎么调,不过有个笨办法,使用try...catch的方式使用MessageBox把出错信息显示出来,我就是这么调的,折腾了一整天,呵呵。
相关参考代码记录
- #region WriteWebConfig 修改web.config的连接数据库的字符串
-
- private bool WriteWebConfig()
-
- {
-
- System.IO.FileInfo FileInfo = new System.IO.FileInfo(this.Context.Parameters["targetdir"] + "/web.config");
-
- if (!FileInfo.Exists)
-
- {
-
- throw new InstallException("Missing config file :" + this.Context.Parameters["targetdir"] + "/web.config");
-
- }
-
-
-
- System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
-
- xmlDocument.Load(FileInfo.FullName);
-
-
-
- bool FoundIt = false;
-
- foreach (System.Xml.XmlNode Node in xmlDocument["configuration"]["appSettings"])
-
- {
-
- if (Node.Name == "add")
-
- {
-
- if (Node.Attributes.GetNamedItem("key").Value == "ConnectionString")
-
- {
-
- Node.Attributes.GetNamedItem("value").Value = String.Format("Persist Security Info=False;Data Source={0};database={1};User ID={2};Password={3};Packet Size=4096;Pooling=true;Max Pool Size=100;Min Pool Size=1", ServerName, DBName, AdminName, AdminPwd);
-
- FoundIt = true;
-
- }
-
- }
-
- }
-
-
-
- if (!FoundIt)
-
- {
-
- throw new InstallException("Error when writing the config file: web.config");
-
- }
-
-
-
- xmlDocument.Save(FileInfo.FullName);
-
- return FoundIt;
-
- }
-
- #endregion
-
- #region WriteRegistryKey 写注册表。安装部署中,直接有一个注册表编辑器,可以在那里面设置。
-
- private void WriteRegistryKey()
-
- {
-
-
-
- RegistryKey hklm = Registry.LocalMachine;
-
- RegistryKey cqfeng = hklm.OpenSubKey("SOFTWARE", true);
-
-
-
- RegistryKey F = cqfeng.CreateSubKey("cqfeng");
-
-
-
- F.SetValue("FilePath", "kkkk");
-
- }
-
- #endregion
- #region Connect 连接IIS服务器
-
- public bool Connect()
-
- {
-
-
-
- if (iis == null)
-
- return false;
-
- try
-
- {
-
- _iisServer = new DirectoryEntry("IIS:" + iis + "/W3SVC/1");
-
- _target = iis;
-
- _connection = new ConnectionOptions();
-
- _scope = new ManagementScope(@"\\" + iis + @"\root\MicrosoftIISV2", _connection);
-
- _scope.Connect();
-
- }
-
- catch
-
- {
-
-
-
- return false;
-
- }
-
- return IsConnected();
-
- }
-
-
-
- public bool IsConnected()
-
- {
-
- if (_target == null || _connection == null || _scope == null) return false;
-
- return _scope.IsConnected;
-
- }
-
- #endregion
-
-
-
- #region IsWebSiteExists 判断网站是否已经存在
-
- public bool IsWebSiteExists(string serverID)
-
- {
-
- try
-
- {
-
- string siteName = "W3SVC/" + serverID;
-
- ManagementObjectSearcher searcher = new ManagementObjectSearcher(_scope, new ObjectQuery("SELECT * FROM IIsWebServer"), null);
-
-
-
- ManagementObjectCollection webSites = searcher.Get();
-
- foreach (ManagementObject webSite in webSites)
-
- {
-
- if ((string)webSite.Properties["Name"].Value == siteName)
-
- return true;
-
- }
-
-
-
- return false;
-
- }
-
- catch
-
- {
-
- return false;
-
- }
-
- }
-
- #endregion
-
-
-
- #region GetNextOpenID 获得一个新的ServerID
-
- private int GetNextOpenID()
-
- {
-
- DirectoryEntry iisComputer = new DirectoryEntry("IIS:localhost/w3svc");
-
- int nextID = 0;
-
- foreach (DirectoryEntry iisWebServer in iisComputer.Children)
-
- {
-
- string sname = iisWebServer.Name;
-
- try
-
- {
-
- int name = int.Parse(sname);
-
- if (name > nextID)
-
- {
-
- nextID = name;
-
- }
-
- }
-
- catch
-
- {
-
- }
-
- }
-
- return ++nextID;
-
- }
-
- #endregion
-
-
-
- #region CreateWebsite 添加网站
-
- public string CreateWebSite(string serverID, string serverComment, string defaultVrootPath, string HostName, string IP, string Port)
-
- {
-
- try
-
- {
-
- ManagementObject oW3SVC = new ManagementObject(_scope, new ManagementPath(@"IIsWebService='W3SVC'"), null);
-
- if (IsWebSiteExists(serverID))
-
- {
-
- return "Site Already Exists...";
-
- }
-
- ManagementBaseObject inputParameters = oW3SVC.GetMethodParameters("CreateNewSite");
-
- ManagementBaseObject[] serverBinding = new ManagementBaseObject[1];
-
- serverBinding[0] = CreateServerBinding(HostName, IP, Port);
-
- inputParameters["ServerComment"] = serverComment;
-
- inputParameters["ServerBindings"] = serverBinding;
-
- inputParameters["PathOfRootVirtualDir"] = defaultVrootPath;
-
- inputParameters["ServerId"] = serverID;
-
-
-
- ManagementBaseObject outParameter = null;
-
- outParameter = oW3SVC.InvokeMethod("CreateNewSite", inputParameters, null);
-
- // 启动网站
-
- string serverName = "W3SVC/" + serverID;
-
- ManagementObject webSite = new ManagementObject(_scope, new ManagementPath(@"IIsWebServer='" + serverName + "'"), null);
-
- webSite.InvokeMethod("Start", null);
-
- return (string)outParameter.Properties["ReturnValue"].Value;
-
- }
-
- catch (Exception ex)
-
- {
-
- return ex.Message;
-
- }
-
- }
-
- public ManagementObject CreateServerBinding(string HostName, string IP, string Port)
-
- {
-
- try
-
- {
-
- ManagementClass classBinding = new ManagementClass(_scope, new ManagementPath("ServerBinding"), null);
-
- ManagementObject serverBinding = classBinding.CreateInstance();
-
- serverBinding.Properties["Hostname"].Value = HostName;
-
- serverBinding.Properties["IP"].Value = IP;
-
- serverBinding.Properties["Port"].Value = Port;
-
- serverBinding.Put();
-
- return serverBinding;
-
- }
-
- catch
-
- {
-
- return null;
-
- }
-
- }
-
- #endregion