最近临时搞了个办证中心的小东东(我现在公司就是搞办证中心网站及软件的),开发完了得找人过去安装或是把网站文件什么的打包发给对方安装。项目分网站文件及SQL数据两部门,也就是说在部署的时候得同时安装网站文件及在SQL数据库中建好相关表、视图等内容。
我使用了VS2005中的安装和部署项目中的“Web安装项目”,大概使用了下发现部署网站相当方便,但部署SQL数据就得在原基础上进行自定义操作了。这东东以前没搞过,比较没有头绪,找了不少资料:
带SQL数据库操作的安装部署视频教程
视频教程带的原码(里面少个WEB项目,想研究的自己添加个WEB项目,然后里面随便加个页面就行了)
视频教程带的PDF
视频教程带的QA
上面的教程看过后基本就对安装部署的自定义操作比较了解了,然后就可以按以上示例进行动手操作了。
我在网上找到的比值得参考的一个全程教学: 如何用VS2005制作Web安装程序 -徐智雄的BLOG(附带: 用VS2005制作网页对IIS进行操作),这里写的更详细点,我这里也就偷偷懒不把全程写一回了,把一些值得注意的地方写下
1、在绑定自定义安装对话框中参数时,如下图所示的地方:
注意:
2、执行SQL语句时那个SQL.TXT要注意的地方
注意:SQL.TXT(可以是其它文件名)的编码要为Unicode,文件中不要包含"GO",如果视图等内容要求必须是批查询中的第一条语句的SQL语句得用EXEC('语句内容')来处理,要不会报错的。如:
我折腾了不少时间才执行成功的SQL(大家好参考下)
如果想在类似查询分析器那里比较方便的进行执行SQL的话可以参考以下代码段,这个我没试过,是调用osql.exe来执行SQL的,应该不会有像SqlCommand执行的问题了
这个问题我找了很久不知道怎么调,不过有个笨办法,使用try...catch的方式使用MessageBox把出错信息显示出来,我就是这么调的,折腾了一整天,呵呵。
相关参考代码记录
我使用了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] ')
![](http://blog.breakn.net/styles/default/images/icon_file.gif)
如果想在类似查询分析器那里比较方便的进行执行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"))
- '调用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
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 Try3、关于调试的问题
这个问题我找了很久不知道怎么调,不过有个笨办法,使用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