现在做了一个程序包括winform程序(跑界面部分),windows服务,winpcap类库
把他们3个做成一个安装包,我现在想安装执行的时候在安装事件里面直接把windows服务和winpcap装上
问题:安装事件在什么地方写
      调用安装windows服务和winpcap的代码怎么实现直接在代码中调用CMD。参考这个 C# codeProcess   p   =   new   Process();  
                p.StartInfo.FileName   =   "cmd.exe";  
                p.StartInfo.UseShellExecute   =   false;  
                p.StartInfo.RedirectStandardInput   =   true;  
                p.StartInfo.RedirectStandardOutput   =   true;  
                p.StartInfo.RedirectStandardError   =   true;  
                p.StartInfo.CreateNoWindow   =   true;  //不显示命令行窗口
                p.Start();  
                p.StandardInput.WriteLine("InstallUtil -i 服务程序集文件名"); //确保InstallUtil在当前目录下  不知道上面这段代码能否实现对windows和winpcap的安装,如果能,写在什么地方呢?都说写在安装事件中,但安装事件在哪??

解决方案 »

  1.   

    你可以写一个继承Install的类,然后在里面处理。也可以写一个CustomAction
      

  2.   


    private static string GetScript(string name)
    {
        Assembly asm = Assembly.GetExecutingAssembly();
        Stream str = asm.GetManifestResourceStream(
                        asm.GetName().Name+ "." + name);
        StreamReader reader = new StreamReader(str);
        return reader.ReadToEnd();
    }
    private static string GetLogin(string databaseServer,
                     string userName,string userPass,string database)
    {
        return "server=" + databaseServer + 
         ";database="+database+";User ID=" + userName +
         ";Password=" + userPass;
    }private static void ExecuteSql(SqlConnection sqlCon)
    {
        string[] SqlLine;
        Regex regex = new Regex("^GO",RegexOptions.IgnoreCase | RegexOptions.Multiline);
        
        string txtSQL = GetScript("install.txt");
        SqlLine = regex.Split(txtSQL);    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)
                {
                    //rollback
                    ExecuteDrop(sqlCon);
                    break;
                }
            }
        }
    }
    private static void ExecuteDrop(SqlConnection sqlCon)
    {    
        if(sqlCon.State!=ConnectionState.Closed)sqlCon.Close();
        sqlCon.Open();
        SqlCommand cmd = sqlCon.CreateCommand();
        cmd.Connection = sqlCon;
        cmd.CommandText = GetScript("uninstall.txt");
        cmd.CommandType = CommandType.Text;
        cmd.ExecuteNonQuery();
        sqlCon.Close();
    }
    public override void Install(IDictionary stateSaver)
    {
        base.Install (stateSaver);    if(Context.Parameters["databaseServer"].Length>0 &&
            Context.Parameters["userName"].Length>0 &&
            Context.Parameters["userPass"].Length>0)
        {
            conStr = GetLogin(
                Context.Parameters["databaseServer"],
                Context.Parameters["userName"],
                Context.Parameters["userPass"],
                "master");        RijndaelCryptography rijndael = new RijndaelCryptography();
            rijndael.GenKey();
            rijndael.Encrypt(conStr);
            //save information in the state-saver IDictionary
            //to be used in the Uninstall method
            stateSaver.Add("key",rijndael.Key);
            stateSaver.Add("IV",rijndael.IV);
            stateSaver.Add("conStr",rijndael.Encrypted);
        }    SqlConnection sqlCon = new SqlConnection(conStr);    sqlCon.Open();
        ExecuteSql(sqlCon);
        if(sqlCon.State!=ConnectionState.Closed)sqlCon.Close();
    }public override void Uninstall(IDictionary savedState)
    {
        base.Uninstall (savedState);    if(savedState.Contains("conStr"))
        {
            RijndaelCryptography rijndael = new RijndaelCryptography();
            rijndael.Key = (byte[])savedState["key"];
            rijndael.IV = (byte[])savedState["IV"];
            conStr = rijndael.Decrypt((byte[])savedState["conStr"]);            
        }    SqlConnection sqlCon = new SqlConnection(conStr);    ExecuteDrop(sqlCon);
    }
    试试吧,我没试
      

  3.   

    一楼的回答思路是对的,谢谢
    二楼的也谢谢你,呵呵不过数据库部分用不到,重写的那install和uninstall方法可以参照
    谁还有具体这方面的实现更好,谢谢
      

  4.   

    在安装类里通过 installutil实现服务安装
    还可使用installshoield安装脚本实现安装
    installutil myservice1.exe
      

  5.   

    可以尝试在命令行执行windows service安装
    参考http://www.cnblogs.com/downmoon/archive/2007/12/29/1019924.html
    http://blog.csdn.net/downmoon/archive/2007/04/24/1581113.aspx
      

  6.   

    继承Installer安装类,然后在部署安装项目那边将程序,windows服务的主输出添加进去,在自定义操作那边添加上操作,应该就可以了
    有试过同时安装2个windows服务,安装一个主程序和一个windows服务都可以成功