对于vs自带的安装部署,说实话真的很有局限性,必备组件里边的组件不全是一大原因(可以对其进行增删改,见浅谈VS安装部署[续])
比如这边只有office2007 pia组件,而没有2010的pia。再如下面的vsto30组件,要是安装了vs的补丁包sp1,这边的vsto30组件则变成vsto30 sp1,不会再出现vsto30,这将直接导致在未安装vsto组件的机器安装软件时报错,如图示
vs安装部署也不至于那么“菜”吧,它也提供了自定义操作(Custom Actions),一定程度上也算是弥补了这一局限性。在这里面我们可以自定义安装前面“系统必备”里面所缺失的组件。
自定义操作类库的原型是这样:
[RunInstaller(true)]
public partial class CustomInstaller : Installer
{
public CustomInstaller()
{
InitializeComponent();
}
/// <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);
}
/// <summary>
/// 安装后处理
/// </summary>
/// <param name="savedState"></param>
protected override void OnAfterInstall(IDictionary savedState)
{
base.OnAfterInstall(savedState);
//获取安装目录,这里的InstallDir要在Custom Actions里面设置,具体如下图示
string targetdir = Context.Parameters["InstallDir"];
targetdir = targetdir.Trim(new char[] { '\'' });
//比如我这里安装2010pia,用bat控制安装,install.bat内容如下
//@echo off
//
//echo Installing Primary Interop Assemblies...
//start /WAIT "" "%~dp0\o2010pia.msi" /quiet ::选择静默安装,避免弹出警告信息
//
//exit
//注意install.bat要包入安装包
ExecuteBat(targetdir + "install.bat");
}
/// <summary>
/// 卸载处理
/// </summary>
/// <param name="savedState"></param>
public override void Uninstall(IDictionary savedState)
{
//卸载时自定义代码
base.Uninstall(savedState);
}
/// <summary>
/// 执行BAT文件
/// </summary>
/// <param name="batPath">BAT文件路径</param>
private void ExecuteBat(string batPath)
{
Process p = new Process();
p.StartInfo.FileName = batPath;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.Start();
}
}
这一切看似很完美了,但用了自定义安装组件时经常导致在xp环境下安装出问题,尤其是安装前选择Everyone(默认是Just me)更是问题多多,自定义安装的组件看似已经执行了安装(一闪而过),但最终却没能成功安装,这样的问题困扰了我许久,至今只有一句话想说:“在‘系统必备’里面有的千万别自定义安装,否则就是自讨苦吃”