Wix打包系列(三)自定义Action(Custom Action)
原文:Wix打包系列(三)自定义Action(Custom Action)
3.1 关于Action
我们已经知道如何生成具有标准安装界面的安装程序了,Windows Installer按照我们的界面设置使用标准的安装步骤进行安装,它的安装过程是由一系列标准的Action组成,通过这些Action来完成对计算机的安装配置;如果我们想自定义安装步骤或者在安装过程中执行自定义的操作,就需要使用自定义的Action。当然,使用Custom Action之前,我们应该先了解一下msi中这些标准的Action。
首先,我们通过Orca工具(参考Windows Installer SDK)打开Sample.msi文件,可以看到使用wix标准安装界面生成的安装程序包含哪些Action,如下图,我们可以看到这些Action的名称和安装顺序,关于Orca以及msi数据库的表和字段的含义,本文不做介绍,有兴趣可以查看msi sdk

这里我们主要关注InstallExecuteSequence 和InstallUISequence表,他们之间的区别是InstallUISequence只有在内置UI的等级是Full UI或者reduced UI时才会起作用,在basic UI 或者silent方式安装时不起作用;关于UI等级 在msi sdk中UILevel Property章节有详细说明。我们定义的Custom Action也可能会包含在这些 Action序列中,通过Sequence来确定执行顺序;当然也可能不包含在Action序列中,当这个Action是由按钮触发的时候。
3.2 Custom Action
下面我们来看看怎么使用Custom Action,我们在代码中Product标签下加入如下代码:
<Property Id='NOTEPAD' Value='Notepad.exe'/>
<CustomAction Id='LaunchFile' Property='NOTEPAD' ExeCommand='[INSTALLDIR]Manual.pdf' Return='asyncNoWait' />
<InstallExecuteSequence>
<Custom Action='LaunchFile' After='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
<CustomAction Id='LaunchFile' FileKey='filFoobarEXE' ExeCommand='' Return='asyncNoWait' />
3.2中的LaunchFile动作在InstallExecuteSequence序列中的InstallFinalize动作之后执行,即便InstallFinalize已经在InstallExecuteSequence的最后了,但是LaunchFile仍然会在完成界面弹出之前执行;一般我们都想在结束界面点击完成按钮之后执行LaunchFile动作,这时我们就需要用到按钮的事件了,把CustomAction动作绑定到按钮的事件中,这样点击结束按钮就可以执行LaunchFile了,操作步骤如下:
<CustomAction Id='LaunchFile' FileKey='filFoobarEXE' ExeCommand='' Return='asyncNoWait' />
然后,我们可以查到WixUI_Mondo模式的结束窗口是ExitDialog,需要给ExitDialog界面的完成按钮添加事件:
<UI Id="MyWixUI_Mondo">
<UIRef Id="WixUI_Mondo" />
<UIRef Id="WixUI_ErrorProgressText" />
<Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" Value="LaunchFile" Order="1">1</Publish>
</UI>
3.4 编写托管的Custom Action
比如我们要在安装之前检查某个数据库连接是否存在,上面的CustomAction设置则不能满足我们的要求,这时我们就需要自己写一个Action 的DLL。这里我们只介绍如何使用c#生成Action ,对于使用VB和c++语言则不做介绍。
如果我们在安装wix之前安装了vs2005或者vs2008,我们就可以很方便的在vs开发环境下生成Action ,首先在解决方案资源管理器中右键解决方案名称,然后选择添加项目,在添加新项目对话框中项目类型选择wix,模板选择c# Custom Action Project,如图:
下面我们在SampleCustomAction类中添加一个连接数据库的方法,代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Deployment.WindowsInstaller;
namespace SampleCustomAction
{
public class CustomActions
{
[CustomAction]
public static ActionResult ConnectDataBase(Session session)
{
session.Log("Begin ConnectDataBase");
// 数据库连接串
string connectionStr = session["CONNECTIONSTRING"];
// 连接数据库方法
//if (DBUtil.ConnectDB(connectionStr))
session["CONNECTSUCCESS"] = "1";
//else
session["CONNECTSUCCESS"] = "0";
return ActionResult.Success;
}
}
}
这里方法实现部分省去了,读者可以自己去实现,数据库连接串CONNECTIONSTRING是在wix源文件中定义的:
<Property Id="CONNECTIONSTRING" Value="data source=(local);user=sa;password=123;initial catalog=master;Persist Security Info=;" />
<Binary Id='ConnectDBClass' SourceFile='$(var.Version)/SampleCustomAction.CA.dll' />
<CustomAction Id='ConnectDB' BinaryKey='ConnectDBClass' DllEntry='ConnectDataBase' />
<CustomAction Id='ConnectError' Error='数据库连接失败' />
<InstallExecuteSequence>
<Custom Action='ConnectDB' After='CostFinalize' />
<Custom Action='ConnectError' After='ConnectDB'><![CDATA[CONNECTSUCCESS <> "1" AND NOT Installed]]></Custom>
</InstallExecuteSequence>
msiexec /i 1.0.0/Sample.msi /l*v Sample.msi.log
打开安装日志,我们可以看到Action执行的日志:
...
...
操作结束 15:24:05: CostFinalize。返回值 1。
MSI (s) (E0:BC) [15:24:05:218]: Doing action: ConnectDB
操作 15:24:05: ConnectDB。
操作开始 15:24:05: ConnectDB。
MSI (s) (E0:F4) [15:24:05:218]: Invoking remote custom action. DLL: C:/WINDOWS/Installer/MSI1A1.tmp, Entrypoint: ConnectDataBase
MSI (s) (E0:04) [15:24:05:218]: Generating random cookie.
MSI (s) (E0:04) [15:24:05:250]: Created Custom Action Server with PID 4108 (0x100C).
MSI (s) (E0:24) [15:24:05:281]: Running as a service.
MSI (s) (E0:24) [15:24:05:281]: Hello, I'm your 32bit Impersonated custom action server.
SFXCA: Extracting custom action to temporary directory: C:/WINDOWS/Installer/MSI1A1.tmp-/
SFXCA: Binding to CLR version v2.0.50727
Calling custom action SampleCustomAction!SampleCustomAction.CustomActions.ConnectDataBase
Begin ConnectDataBase
MSI (s) (E0!F4) [15:24:05:687]: PROPERTY CHANGE: Adding CONNECTSUCCESS property. Its value is '1'.
MSI (s) (E0!F4) [15:24:05:687]: PROPERTY CHANGE: Modifying CONNECTSUCCESS property. Its current value is '1'. Its new value: '0'.
操作结束 15:24:05: ConnectDB。返回值 1。
MSI (s) (E0:BC) [15:24:05:796]: Doing action: ConnectError
操作 15:24:05: ConnectError。
操作开始 15:24:05: ConnectError。
数据库连接不存在
MSI (s) (E0:BC) [15:24:06:703]: 产品: Foobar 1.0 -- 数据库连接不存在
操作结束 15:24:06: ConnectError。返回值 3。
操作结束 15:24:06: INSTALL。返回值 3。
...
...
1: csc.exe /target:library /reference:path/Microsoft.Deployment.WindowsInstaller.dll /out:CheckPID.dll CheckPID.cs
2: MakeSfxCA.exe path/CheckPIDPackage.dll path/sfxca.dll path/CheckPID.dll path/CustomAction.config path/Microsoft.Deployment.WindowsInstaller.dll
Wix打包系列(三)自定义Action(Custom Action)的更多相关文章
- Wix打包系列(四) 自定义UI
原文:Wix打包系列(四) 自定义UI 除了标准的安装界面,如果我们要在安装时需要提供一些额外的信息时,这时就需要自定义界面来显示和录入这些信息. 4.1 自定义对话框 如上一章中我们测试数据库的连 ...
- Wix打包系列(二)用户界面和本地化操作
原文:Wix打包系列(二)用户界面和本地化操作 上一章节,我们已经大概知道如何对文件进行打包安装,不过我们也注意到,通过对Sample.wxs的编译链接,生成的msi安装包没有任何用户界面,只有一个安 ...
- Wix打包系列 (六)制作升级和补丁包
原文:Wix打包系列 (六)制作升级和补丁包 前面我们已经知道怎么制作一个完整安装包了,但我们的软件往往不能一次性就满足客户的需要,当客户需要我们给软件进行升级的时候,我们应该怎么做呢? 在这之前,我 ...
- Wix打包系列(一)如何使用wix制作安装程序
原文:Wix打包系列(一)如何使用wix制作安装程序 最近由于项目需要,需要给客户制作安装程序,一开始使用vs2005自带的打包工程来打包,但用了一段时间发现vs打包太死板,而且使用起来问题很多.收费 ...
- Wix打包系列(五) 部署数据库
原文:Wix打包系列(五) 部署数据库 很多人在使用vs进行打包的时候,经常会为数据库部署的问题犯愁,即便是重写Installer类的方法,也不是很可靠方便,下面我们来看看在wix中如何部署数据库. ...
- Wix打包系列(七) 添加系统必备组件的安装程序
原文:Wix打包系列(七) 添加系统必备组件的安装程序 我们知道在vs的打包工程中添加系统必备组件是一件很容易的事情,那么在wix中如何检测系统必备组件并在安装过程中安装这些组件.这里以.Net Fr ...
- WIX Custom Action (immediate, deffered, rollback)
Following content is directly reprinted from From MSI to WiX, Part 19 - The Art of Custom Action, Pa ...
- Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送
Android高效率编码-第三方SDK详解系列(三)--JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送 很久没有更新第三方SDK这个系列了,所以更新一下这几天工作中使用到的推送, ...
- Android 自定义title 之Action Bar
Android 自定义title 之Action Bar 2014-06-29 飞鹰飞龙... 摘自 博客园 阅 10519 转 25 转藏到我的图书馆 微信分享: Action Ba ...
随机推荐
- MongoDB---性能优化---(1)
MONGODB数据架构 升级解决.计划 发现问题 应用server用户数的突然涌入,创建server反应慢 检查server,我发现,每次反应非常慢,至30ops 检查过程 .发现数据库查询缓 ...
- sqlserver05 字符串拆分
-- 规则:将 gs-abc-aa-aa 拆分为一下字符 -- gs-abc-aa-aa -- gs-abc-aa -- gs-abc -- gs select * from dbo.f_split( ...
- cocos2d-x 3.0来做一个简单的游戏教程 win32平台 vs2012 详解献给刚開始学习的人们!
原代码来自于网络,因为cocos2d-x 3.0的资料,的确不多,与曾经版本号的接口非常难对上, 所以网上非常多样例都无法调试,对于新学习cocos2d-x 的同学,难度添加了,所以出一个超具体的样例 ...
- hadoop学习;hadoop伪分布搭建
先前已经做了准备工作安装jdk什么的,以下開始ssh免password登陆.这里我们用的是PieTTY工具,当然你也能够直接在linux下直接操作 ssh(secure shell),运行命令 ssh ...
- Servlet过滤器——使用过滤器禁止浏览器缓存页面
1.概述 IE缓存虽然能提高已储存网站的访问速度,但是过度的IE缓存会影响浏览器的响应速度.同时还可能为网站的运行带来一些不必要的麻烦.例如:可能会因为浏览器缓存的应用,而导致Web服务器不能准确的计 ...
- Oracle 排序规则
<pre name="code" class="html">SQL> select * from t1 where id>=1 and ...
- session对象和applicatione对象
ASP.NET 的常用对象有:response对象.request对象.application对象.server对象.session对象.下面主要讨论session对象和cookie对象. sessi ...
- VC/MFC 工具栏上动态添加组合框等控件的方法
引言 工具条作为大多数标准的Windows应用程序的一个重要组成部分,使其成为促进人机界面友好的一个重要工具.通过工具条极大方便了用户对程序的操作,但是在由Microsoft Visual C++开发 ...
- MFC 在对话框显示图片的多种方法
我们先从简单的开始吧.先分一个类: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的路径即可载入) 为方便说明,我们已经建好一 ...
- memcached vs MySQL Memory engine table 速度比较_XMPP Jabber即时通讯开发实践_百度空间
memcached vs MySQL Memory engine table 速度比较_XMPP Jabber即时通讯开发实践_百度空间 memcached vs MySQL Memory engin ...