C#安装项目 连接数据库及枚举Windows服务列表

前几天做了一个用Visual Studio2008打包的项目 现把过程几下以供日后参考!
选择"安装项目”<!-- 是安装项目,不是安装向导-->然后在“解决方案资源管理器”中右键添加一个“类库”并删除class.cs文件然后点击类库创建“安装程序类”名字自取、由于VS打包安装项目的文章网上太多。这里就不重复赘述。大家可自行Baidu or Google 下面说说关于枚举Windows服务并控制其服务状态。首先必须得引入System.ServiceProcess.dll动态链接库这个.dll文件在VS项目里找不到大家可在网上下载(自少我是在网上下载的)并引入到项目中然后using System.ServiceProcess;引入命名空间。由于本人懒。本文以后关于类的所属命名空间不再出现大家可以将类名Copy在MSDN里自行查找其命名空间 So easy! 好了废话不多说。贴代码。!
        #region 判断服务是否存在
        /// <summary>
        /// 枚举所有服务并判断服务是否存在
        /// </summary>
        /// true为存在 false为不存在
        public  bool HaveService()
        {
            ServiceController[] services = ServiceController.GetServices();//获取Windows所有服务的集合


            foreach (ServiceController s in services)
            {
                if ( s.ServiceName.Equals("ShenLongShiBieService") )//字符串里为服务名.后来发现可直接用ServiceController service = new //ServiceController("ShenLongShiBieService");生成ServiceController 对象 并判断其值是否为null来判断服务是否存在 //这样就少了遍历所有Windows服务所需的时间。看来自己还是太嫩!!
                {
                    return true;
                }
            }




            return false;
        }
        #endregion
//额 突然发现自己在代码中的注释比自己嘴上吹的还好。所以就为省事直接贴代码了。。。。

        ///下面为连接并创建数据库的代码!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       




        ///  
        /// 清理所有正在使用的资源。
        /// 
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }




        #region 组件设计器生成的代码
        /// 
        /// 设计器支持所需的方法 - 不要使用代码编辑器修改
        /// 此方法的内容。
        /// 
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
        }
        #endregion




        #region 重载自定义安装方法




        /// <summary>
        /// 安装前的动作
        /// </summary>
        /// <param name="savedState"></param>
        protected override void OnBeforeInstall(IDictionary savedState)
        {
            base.OnBeforeInstall(savedState);
        }




        /// <summary>
        /// 安装时的动作
        /// </summary>
        /// <param name="stateSaver"></param>
        public override void Install(IDictionary stateSaver)
        {
            base.Install(stateSaver);
            string databaseServer = Context.Parameters["server"].ToString();
            string userName = Context.Parameters["user"].ToString();
            string userPass = Context.Parameters["pwd"].ToString();
            targetdir = this.Context.Parameters["targetdir"].ToString();
            dbName = Context.Parameters["dbname"].ToString();
            string radio = Context.Parameters["radio"].ToString();//单选按钮的返回值
            bool completedInstall = false;//是否是“完全安装” true为是 false 为否
            SqlConnection sqlCon = new SqlConnection();//数据库连接
            conStr = GetLogin(databaseServer, userName, userPass, "master");




            //改变“完全安装”的值
            if (radio.Equals("2"))
            {
                completedInstall = true;
            } 
           
            //------------将用户填写的信息存入UserInfo.txt文件中以便卸载的时候调用-------------------------------------------------------
            //string[] userInfo = new string[3];
            //userInfo[0] = completedInstall.ToString();//存入completedInstall的字符串值以便确定用户的安装模式
            //userInfo[1] = conStr;//存入数据库连接字符串
            //userInfo[2] = dbName;//存入数据库名称
            //File.WriteAllLines(targetdir + "UserInfo.txt", userInfo);
            //---------------------------------------------------------------------------------------------------------------------------




            //-------------------将用户信息写入ShenLongShiBie.exe.config文件以便卸载以及一些其他操作-------------------------------------
            string fileName = targetdir + @"ShenLongShiBie.exe.config";//安装文件夹下的ShenLongShiBie.exe.config文件路径
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();//产生一个ShenLongShiBie.exe.config映射防止henLongShiBie.exe.config.config的产生
            fileMap.ExeConfigFilename = fileName;//将ShenLongShiBie.exe.config的路径赋值给fileMap
            Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
            //将用户信息写入配置文件
            config.AppSettings.Settings["InstallModel"].Value = todes(completedInstall.ToString());
            config.AppSettings.Settings["ConnStr"].Value = todes(conStr);
            config.AppSettings.Settings["UserName"].Value = todes(userName);
            config.AppSettings.Settings["UserPass"].Value = todes(userPass);
            config.AppSettings.Settings["DBName"].Value = todes(dbName);
            config.Save();//将用户信息保存进配置文件 
            //---------------------------------------------------------------------------------------------------------------------------
            try
            {
                //下面为选择“完全安装”模式 安装的操作
                if (completedInstall)
                {
                    //如果服务未安装则运行批处理文件安装服务
                    if (!HaveService())
                    {                  
                        Process process = new Process();
                        process.StartInfo.WorkingDirectory = targetdir;
                        process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                        process.StartInfo.FileName = "installService.bat";//installService 的路径
                        process.Start();
                    }
                
                    Thread.Sleep(5000);//先等待5秒让服务安装
                    //5秒后服务还未装好 再等待5秒知道服务装好为止
                    while (!HaveService())
                    {
                        Thread.Sleep(5000);
                    }
                    
                    //str += (HaveService()).ToString();
                    //File.WriteAllText("E:\\test3.txt", str);//将路径写入文件以便测试




                    //如果服务未启动则启动服务
                    if (HaveService())
                    {
                        ServiceController service = new ServiceController("ShenLongShiBieService");
                        service.Refresh();
                        //string str1 = service.Status.ToString() + "," + ServiceControllerStatus.Stopped.ToString();
                        
                        int count = 0;
                        while (service.Status.ToString().Equals(ServiceControllerStatus.Stopped.ToString()))//如果服务一直不启动就往死里启动!!!
                        {//这里其实不用循环用if一次就可以启动服务,但是当初调试的时候判断失误是service.Status.ToString().Equals(ServiceControllerStatus.Stopped.ToString()
//没注意到判断条件的最终值所以写成这样来测试 望大家见谅。!
                            service.Start();
                            
                            //小心使得万年船
                            count++;                       
                            if (10 == count)
                            {
                                break;
                            }
                            service.Refresh();
                        }
                        //str1 += "   " + service.Status.ToString().Equals(ServiceControllerStatus.Stopped.ToString()).ToString();
                        //str1 += count.ToString();
                        //File.WriteAllText("E:\\test4.txt", str1);//将路径写入文件以便测试
                    }




                    sqlCon.ConnectionString = conStr;//数据库连接字符串
                    sqlCon.Open();//打开数据库




                    //-----------这里对SQLScript.txt文件进行操作-----------------------------
                    //string str = FileToString();
                    //string str2 = str.Replace("{dbname}", "Database");
                    //StringToFile(str2);
                    //-----------------------------------------------------------------------




                    ExecuteSql(sqlCon, "SQLScript.txt");//执行SQL脚本文件 




                    //---------为了不破坏代码结构,将SQLScript.txt文件恢复-------------------
                    //string str3 = FileToString();
                    //StringToFile(str3.Replace("Database", "{dbname}"));
                    //-----------------------------------------------------------------------




                    if (sqlCon.State != ConnectionState.Closed)
                    {
                        sqlCon.Close();
                    }
                }
               
            }
            catch (SqlException)
            {
                MessageBox.Show("安装失败!\n数据库配置有误,请正确配置信息!");
                config.AppSettings.Settings["InstallModel"].Value = todes("False");
                config.Save();
                if (sqlCon.State != ConnectionState.Closed) sqlCon.Close();
                this.Rollback(stateSaver);
            }
        }




        /*
        /// <summary>
        /// 返回当前项目跟路径
        /// </summary>
        /// <returns></returns>
        public string GetProjectRootPath()
        {
            Assembly asm = Assembly.GetExecutingAssembly();
            string str = asm.GetManifestResourceStream("SQLScript.txt").ToString();
            string path = Path.GetDirectoryName(str);
            Directory.SetCurrentDirectory(path);
            path = Directory.GetCurrentDirectory();




            return path;
        }
      
        /// <summary>
        /// 将文件内容返回为字符串形式
        /// </summary>
        /// 
        public string FileToString()
        {




            return GetScript("SQLScript.txt");
        }
        
        /// <summary>
        /// 将字符串内容写如文件内
        /// </summary>
        /// 
        public void StringToFile(string str)
        {
            
            File.WriteAllText(asm.GetName().Name + "." + "SQLScript.txt", str);
        }
          */




        protected override void OnAfterInstall(IDictionary savedState)
        {
            base.OnAfterInstall(savedState);
        }




        public override void Rollback(IDictionary savedState)
        {
            base.Rollback(savedState);
        }




        #endregion




        #region 数据操作方法
        //从资源文件获取中数据执行脚本
        private static string GetScript(string name)
        {
            Assembly asm = Assembly.GetExecutingAssembly();
            Stream str = asm.GetManifestResourceStream(asm.GetName().Name + "." + name);
            StreamReader reader = new StreamReader(str, System.Text.Encoding.Default);
            System.Text.StringBuilder output = new System.Text.StringBuilder();
            string line = "";
            while ((line = reader.ReadLine()) != null)
            {
                output.Append(line + "\n");
            }
            return output.ToString();
        }




        //获取数据库登录连接字符串
        private static string GetLogin(string databaseServer, string userName, string userPass, string database)
        {
            return "server=" + databaseServer + ";database=" + database + ";User ID=" + userName + ";Password=" + userPass + ";connect timeout=300;";
        }




        //执行数据库脚本方法
        private static void ExecuteSql(SqlConnection sqlCon, string sqlfile)
        {
            string[] SqlLine;
            Regex regex = new Regex("^GO", RegexOptions.IgnoreCase | RegexOptions.Multiline);




            string txtSQL = GetScript(sqlfile);
            string str = txtSQL.Replace("{path}", targetdir);//修改路径为安装路径
            string str2 = str.Replace("{dbname}", dbName);//修改数据库名称
            //File.WriteAllText("E:\\test2.txt",str2);//将路径写入文件以便测试




            SqlLine = regex.Split(str2);




            if (sqlCon.State != ConnectionState.Closed) sqlCon.Close();
            sqlCon.Open();




            SqlCommand cmd = sqlCon.CreateCommand();
            cmd.Connection = sqlCon;




            foreach (string line in SqlLine)
            {
                if (line.Length > 0)
                {
                    cmd.CommandText = line;
                    cmd.CommandType = CommandType.Text;
                    try
                    {
                        cmd.ExecuteNonQuery();
                    }
                    catch (SqlException ex)
                    {
                        //rollback
                        string ss = ex.Message;




                        break;
                    }
                }
            }
        }
        #endregion




        //卸载安装包方法
        public override void Uninstall(IDictionary savedState)
        {
            targetdir = this.Context.Parameters["targetdir"].ToString();
            //string[] userInfo = File.ReadAllLines(targetdir + "UserInfo.txt");//将用户的数据库信息读取出来以便卸载操作
            string fileName = targetdir + @"ShenLongShiBie.exe.config";//安装文件夹下的ShenLongShiBie.exe.config文件路径
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();//产生一个ShenLongShiBie.exe.config映射防止ShenLongShiBie.exe.config.config的产生
            fileMap.ExeConfigFilename = fileName;//将ShenLongShiBie.exe.config的路径赋值给fileMap
            Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
            string installModel = redes(config.AppSettings.Settings["InstallModel"].Value);




            //如果服务已经安装则卸载服务
            if (HaveService())
            {




                Process process = new Process();
                process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                process.StartInfo.WorkingDirectory = targetdir;
                process.StartInfo.FileName = "UnInstallService.bat";//UnInstallService 的路径
                process.Start();
            }




            if (installModel.Equals("True"))//true为完全模式 false为经典模式
            {
                //删除数据库
                SqlConnection sqlCon = new SqlConnection();
                string conStr = redes(config.AppSettings.Settings["ConnStr"].Value);
                sqlCon.ConnectionString = conStr;//数据库连接字符串




                if (sqlCon.State == ConnectionState.Closed)
                {
                    sqlCon.Open();




                }




                dbName = redes(config.AppSettings.Settings["DBName"].Value);
                string dropSql = "drop database " + dbName;




                //执行删除数据库代码
                if (sqlCon.ConnectionString != null)
                {
                    ExecuteDrop(sqlCon, dropSql);
                }
            }




            base.Uninstall(savedState);
        }




        //删除数据库
        private static void ExecuteDrop(SqlConnection sqlCon , string sql)
        {
            if (sqlCon.State != ConnectionState.Closed)
            {
                sqlCon.Close();
            }




            sqlCon.Open();
            SqlCommand cmd = new SqlCommand(sql, sqlCon);
            cmd.ExecuteNonQuery();
            sqlCon.Close();
        }
//还是老话关于安装项目的简单制作Baidu Goole遍地开花随便搜就搜到一大框
//另外redes();todes();分别是解密和加密的函数 由于这两个函数并非本人所写,出于天地良心,道德规范,三从四德,三教九流,乱七八糟避免世人舆论。就让它们永远长眠
//在我的电脑里吧。就不对外发布非本人的劳动成果了 嘿嘿!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值