安装部署的问题

      没有做过安装盘,因为一直做的都是项目,现场开发比较多,所以基本都是做的文件复制,而且是做的ASP.NET开发,所以部署更简单了,只要复制文件然后修改一下数据库配置就可以了。不过由于一个客户比较认真(他也认为直接复制更简单、方便),再加上市场上需要发布,所以就做了一个安装盘。
      想找一下现成的安装工具,比较好的要花钱,免费的效果又不好,而且做Web的发布相对简单,也不想去花钱买安装工具。有人说VS.NET的安装部署方案太简单,不好用。但由于是集成的,我们决定还是用VS.NET做安装盘。
      安装程序的具体工作就是:把程序复制到硬盘,然后在安装目录上创建虚拟目录,创建对应的数据库并配置。由于数据库允许重新创建、安装、配置,所以把程序安装和数据库安装分开了。前面的工作VS.NET的部署都能非常容易的完成,但创建虚拟目录需要自己处理了。
      也很简单,就是需要创建一个安装类库,继承自System.Configuration.Install.Installer,然后就可以自己处理的。下面是一个代码片断:

using System;
using System.Xml;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using Microsoft.Win32;
using System.IO;

namespace MyInstall
{
/// <summary>
/// CreateDirVirtual 的摘要说明。
/// </summary>

[RunInstaller(true)]
public class CreateDirVirtual : System.Configuration.Install.Installer
{
/// <summary>
/// 必需的设计器变量。
/// </summary>

private System.ComponentModel.Container components = null;
/// <summary>
/// 安装状态保存用的,也可以不定义做为参数传递给相应的方法
/// </summary>

private System.Collections.IDictionary state = null ;

public CreateDirVirtual()
{
// 该调用是设计器所必需的。
InitializeComponent();

// TODO: 在 InitComponent 调用后添加任何初始化
}

/// <summary>
/// 安装,即安装程序时会调用这个方法
/// </summary>
/// <param name="stateSaver"></param>

public override void Install(System.Collections.IDictionary stateSaver)
{
//保存安装信息
state = stateSaver ;
base.Install(stateSaver);
//创建虚拟目录的方法
this.Createvir();
}

/// <summary>
/// 卸载,当卸载程序时调用的方法
/// </summary>
/// <param name="savedState"></param>

public override void Uninstall(IDictionary savedState)
{
//保存状态。需要注意的是:安装和卸载时并不在一个进程中,所以savedState并不相同
state = savedState ;
base.Uninstall (savedState);
//删除虚拟目录
DeleteDir(true) ;
}

/// <summary>
/// 安装失败回滚时调用
/// </summary>
/// <param name="savedState"></param>

public override void Rollback(IDictionary savedState)
{
//保存状态
state = savedState ;
base.Rollback (savedState);
//删除虚拟目录
this.DeleteDir(false) ;
}


/// <summary>
/// 删除虚拟目录
/// </summary>

public void DeleteDir(bool flag)
{
//没有参数,直接用变量处理的,取中安装信息中安装的虚拟目录的状态,如果包含,则删除,否则不处理
if(state != null && state["InstDirVirtual"] != null )
{
string virname = (string)state["InstDirVirtual"] ;
//这段代码是删除虚拟目录的,网上有现成的代码,不再显示了
}

}

//添加一个虚拟目录
public void Createvir()
{
//得到虚拟目录和安装路径
string virname="";
string setupPath="";
string virPath="";
string apprPath="";
//下面取出的注册表的信息都是VS.NET安装程序中保存到注册表中的
RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\CorpName");
string keyName = key.GetValue("LastKey").ToString() ;
key.Close() ;

key
= Registry.LocalMachine.OpenSubKey("SOFTWARE\\CoprName\\" + keyName,true) ;
//取虚拟目录的名字,是VS.NET安装过程中增加的文本输入对话框保留的。
virname = key.GetValue("DirVirtual").ToString();
string virBak = virname ;
//安装目录也是同样的。
setupPath = key.GetValue("ProgramFolder").ToString();
virPath
= Path.Combine( setupPath, keyName) + @"\";
//判断虚拟目录是否安装的代码,略

//把虚拟目录名保存到安装信息中,这些信息会保存到系统中以备卸载时使用
state["InstDirVirtual"] = virname ;

//其他处理

}

#region Component Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>

private void InitializeComponent()
{
components
= new System.ComponentModel.Container();
}

#endregion

}

}

      开始是我同事写的,还说卸载或安装失败时虚拟目录没有删除。呵呵,他把VS.NET想象的太聪明了,所有的都看成了一个事务会自动 回滚。删除或安装失败回滚的操作还是要自己写的,就是要重载Uninstall和Rollback方法,保存到stateServer中的信息会写到系统中保存起来的,所以我们可以在里面保留一些自己的标识,也是我们卸载自己定义安装类安装的程序的一个重要消息来源。
      最后只要在安装部署的项目中增加上面的输出(程序集,我把安装类和安装部署项目放在一个解决方案中,直接增加项目输出即可),然后在安装部署项目的自定义操作中的安装、回滚、卸载操作中分别增加这个安装类项目的输入即可。
      其实做起来非常简单,可能就是开始要自己写一些操作比较麻烦。如果不是特别需要,感觉这样更加灵活。更重要的是:免费的,不怕用破解的安装工具对企业不利了。
     
posted @ 2005-04-20 16:17  海阔天空  阅读(1987)  评论(4编辑  收藏  举报