WEB程序打包详解:(连接SQL2005数据库,修改配置文件,建立虚拟目录)

做了一个web的打包程序,和大家分享一下。

第一步:新建——文件——项目,弹出对话框

 

如图,选择安装和部署——安装项目
这里要解释一下了,一般来说,制作web安装程序选择web安装项目,而我没有选择web安装项目的原因是web安装项目制作出来的安装包是不可以选择软件的安装路径的,而安装项目制作出来的安装包是可以选择软件的安装目录的。
第二步:右键解决方案中的安装项目——视图——文件系统
 如图
弹出
这样的文件系统界面,将你发布完的文件复制到应用程序文件夹下
第三步:右键解决方案中的安装项目——视图——用户界面(和第二步一样,不截图了)弹出下图
其中客户信息根据项目需求可有可无,文本框(A)文本框(B)要是配置数据库连接和虚拟路径的朋友们还是要加的,移动到安装文件夹之上。
第四步:右键文本框(A)——属性窗口,如图
 
解释一下,Edit1Property和Edit2Property是自定义的,朋友们可以随便写,但是要有意义并且能记住,等会儿会用的。
第五步:右键文本框(B)——属性窗口,如图
 
 在解释,Edit1Property,Edit2Property,Edit3Property,Edit4Property均同上,唯一解释的是Edit2Value中填写的值是默认值,朋友们根据个人情况选填。
第六步:右键解决方案——添加——新建项目——类库,删除Class1.CS文件。在这个类库上右键——添加——新建项
如图,选择安装程序类
第七步:右键解决方案中的安装项目——添加——项目输出,如下图
下拉框中就是你刚才建的类库名称,选择主输出——确定。
第八步:右键解决方案中的安装项目——视图——自定义操作,如下图
右键安装——添加自定义操作,选择应用程序文件夹下面的主输出——确定。
这时在安装文件夹下面就多了一个主输出,点击一下,属性如下图
图片可能看不清楚,主要只改一个属性,CustomActionData
这个值很重要
/dbname=[DBNAME] /password=[PASSWORD] /user=[USERNAME]  /server=[DBSERVERNAME] /iis=[IISSERVER] /port=[PORT] /targetdir="[TARGETDIR]/"
这么重要就解释一下,小写的字母全是你建的那个安装程序类中要用到的字段,这个属性主要就是传值用的,将安装信息通过这个属性传入给安装程序类,大写的字母就是当时文本框(A)文本框(B)中你自定义的那些值,targetdir是获得软件的安装目录用的。
到这里,基本上就没有安装项目什么事了,接下来重点在安装程序类。

首先:准备工作,我所用到的引用
以下是这个类的所有代码
using System;
using System.IO;
using System.DirectoryServices;
using System.Reflection;
using System.Data;
using System.Data.SqlClient;
using System.Configuration.Install;
using System.Management;
using System.Collections;
using Microsoft.Win32;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Security.AccessControl;
using IWshRuntimeLibrary;
using System.Windows.Forms;
using System.Diagnostics;
 
namespace ***ClassLibrary
{
    [RunInstaller(true)]
    public partial class ***Installer : Installer
    {
        public ***Installer()
        {
            InitializeComponent();
        }
        #region 变量
        private string server = string.Empty;
        private string dbname = string.Empty;
        private string user = string.Empty;
        private string password = string.Empty;
        private string dir = string.Empty;
        private string iis = string.Empty;
        private string port = string.Empty;
        #endregion

        #region 创建快捷方式(这个WEB快捷方式的创建方法,就是在桌面上创建了一个url的文件)
        private void CreateKJFS()
        {
            StreamWriter sw = new StreamWriter(System.IO.File.Open(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "", FileMode.Create, FileAccess.Write));
            sw.WriteLine("[InternetShortcut]");
            sw.WriteLine("URL=http://"+iis+"/" + port);
            sw.WriteLine("IconFile=" + dir.Substring(0, dir.LastIndexOf("//")) + "");
            sw.WriteLine("IconIndex=0");
            sw.Flush();
            sw.Close();
        }
        #endregion

        #region 移动数据库(解释,为什么要移动数据库呢?主要是我的数据库文件是和发布文件一起放入了应用程序文件夹中,这样在卸载的时候就会默认卸载掉我的数据库,后果十分严重,所以,我在安装目录下创建了一个文件夹Data,根据条件移动文件,由于是代码自动创建的文件夹,所以卸载时就不会被卸载掉了)
        private void MoveData()
        {
            if (!Directory.Exists(dir + "")) //如果不存在Data文件夹
            {
                Directory.CreateDirectory(dir + ""); //创建Data文件夹
                Directory.Move(dir + "", dir + ""); //移动文件
                Directory.Move(dir + "", dir + ""); //同上
                AddDB();//附加数据库(方法在下面)
            }
            else //如果存在Data文件夹
            {
                if (System.IO.File.Exists(dir + "") && System.IO.File.Exists(dir + "")) //并且存在数据库文件
                {
                    LeaveDB(); //分离数据库
                    DialogResult r1 = MessageBox.Show("您确定要用原始数据替换您的现有数据吗?替换前建议您先备份好现有数据,一旦替换,数据将无法恢复!","注意", MessageBoxButtons.YesNo, MessageBoxIcon.Hand);
                    int ss1 = (int)r1;
                    if (ss1 == 6) //如果确定替换
                    {
                        System.IO.File.Delete(dir + ""); //删除文件
                        System.IO.File.Delete(dir + ""); //同上
                        Directory.Move(dir + "", dir + ""); //移动文件
                        Directory.Move(dir + "", dir + ""); //同上
                        AddDB(); //附加数据库
                    }
                    else
                    {
                        AddDB(); //附加数据库
                    }
                }
                else //存在文件夹但是不存在文件
                {
                    Directory.Move(dir + "", dir + "");
                    Directory.Move(dir + "", dir + "");
                    AddDB();
                }
            }
        }
        #endregion

        #region 附加数据库
        private void AddDB()
        {
            string connStr = string.Format("data source={0};user id={1};password={2};persist security info=false;packet size=4096", server, user, password);
            string strSql = "if not exists (select * From master.dbo.sysdatabases where name='" + dbname + "') begin EXEC sp_attach_db  @dbname  =  N'" + dbname + "'," + "@filename1  =  N'" + dir + "," + "@filename2  =  N'" + dir + " end";
            ExecuteSql(connStr, "master", strSql);
        }
        #endregion

        #region 分离数据库
        private void LeaveDB()
        {
            string connStr = string.Format("data source={0};user id={1};password={2};persist security info=false;packet size=4096", server, user, password);
            string strSql = "EXEC sp_detach_db '数据库名称', 'true' ";
            ExecuteSql(connStr, "master", strSql);
        }
        #endregion

 

 

 


        #region 创建虚拟目录(这段是网上copy的,不是自己做的不敢解释)
        private void CreateVirtualDir()
        {
            try
            {
                string constIISWebSiteRoot = "IIS://" + iis + "/W3SVC/1/ROOT";
                DirectoryEntry root = new DirectoryEntry(constIISWebSiteRoot);
                DirectoryEntry newRoot = root.Children.Add(port, root.SchemaClassName);
                newRoot.Properties["Path"][0] = dir;
                newRoot.Properties["AppIsolated"][0] = 2;             // 值 0 表示应用程序在进程内运行,值 1 表示进程外,值 2 表示进程池
                newRoot.Properties["AccessScript"][0] = true;          // 可执行脚本
                newRoot.Invoke("AppCreate", true);
                newRoot.Properties["DefaultDoc"][0] = "Default.aspx";//设置起始页
                newRoot.Properties["AppFriendlyName"][0] = port;   // 应用程序名
                newRoot.CommitChanges();
                root.CommitChanges();
                string fileName = Environment.GetEnvironmentVariable("windir") + @"/Microsoft.NET/Framework/v2.0.50727/aspnet_regiis.exe";
                ProcessStartInfo startInfo = new ProcessStartInfo(fileName);
                //处理目录路径
                string path = newRoot.Path.ToUpper();
                int index = path.IndexOf("W3SVC");
                path = path.Remove(0, index);
                //启动aspnet_iis.exe程序,刷新教本映射
                startInfo.Arguments = "-s " + path;
                startInfo.WindowStyle = ProcessWindowStyle.Hidden;
                startInfo.UseShellExecute = false;
                startInfo.CreateNoWindow = true;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardError = true;
                Process process = new Process();
                process.StartInfo = startInfo;
                process.Start();
                process.WaitForExit();
                string errors = process.StandardError.ReadToEnd();
                if (errors != string.Empty)
                    throw new Exception(errors);
            }
            catch (Exception ee)
            {
                MessageBox.Show("虚拟目录创建失败!您可以手动创建! " + ee.Message, "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
            }
        }
        #endregion

        #region 修改web.config的连接数据库的字符串
        private void WriteWebConfig()
        {
            System.IO.FileInfo FileInfo = new System.IO.FileInfo(dir + "/web.config");
            if (!FileInfo.Exists) //不存在web.config文件
            {
                throw new InstallException("没有找到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"]["connectionStrings"])
            {
                if (Node.Name == "add")
                {
                    if (Node.Attributes.GetNamedItem("name").Value == "配置文件中name的值")
                    {
                        Node.Attributes.GetNamedItem("connectionString").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", server, dbname, user, password);
                    FoundIt = true;
                    }  
                }
            }
            if (!FoundIt)
            {
                throw new InstallException("修改web.config配置文件失败!");
            }
            xmlDocument.Save(FileInfo.FullName);
        }
        #endregion

        #region 执行SQL语句所用方法
        private void ExecuteSql(string connStr, string DatabaseName, string Sql)
        {
            SqlConnection conn = new SqlConnection(connStr);
            SqlCommand cmd = new SqlCommand(Sql, conn);
            conn.Open();
            conn.ChangeDatabase(DatabaseName);
            try
            {
                cmd.ExecuteNonQuery();
            }
            finally
            {
                conn.Close();
            }
        }
        #endregion
 
 #region Install 安装(安装主方法)
        public override void Install(IDictionary stateSaver)
        {
            base.Install(stateSaver);
            dir = this.Context.Parameters["targetdir"].ToString();
            server = this.Context.Parameters["server"].ToString();
            dbname = this.Context.Parameters["dbname"].ToString();
            user = this.Context.Parameters["user"].ToString();
            password = this.Context.Parameters["password"].ToString();
            iis = this.Context.Parameters["iis"].ToString();
            port = this.Context.Parameters["port"].ToString();
            //移动数据库
            MoveData();
            //创建虚拟目录
            CreateVirtualDir();
            //重写Config
            WriteWebConfig();
            //创建快捷方式
            CreateKJFS();
        }
        #endregion
    }
}
posted @ 2012-01-31 14:20  踏浪帅  阅读(771)  评论(0编辑  收藏  举报