#《Wix》的笔记-Custom Action
一般使用步骤为,首先定义CustomAction,然后加入执行序列中, 基本示例如下:
<CustomAction Id="MyAction" Execute="deferred" Return="check" ... />
<InstallExecuteSequence>
<Custom Id="MyAction" After="InstallInitialize" />
</InstallExecuteSequence>
用before after 来定义顺序
有七种类型Action的用途
-
设置安装属性。
-
设置安装目录
-
运行嵌入式vb脚本。
-
调用外部vb脚本文件
-
触发一个可执行文件
-
调用一个动态链接库的方法。
-
发出一个错误提示终止安装。
http://stackoverflow.com/questions/7176551/how-to-link-custom-action-to-control-event
1.设置安装属性
用自带的Property ARPINSTALLLOCATION 来存储安装目录。
<CustomAction Id="rememberInstallDir" Property="ARPINSTALLLOCATION" Value="[INSTALLLOCATION]" />
设置执行顺序
<InstallExecuteSequence>
<Custom Action="rememberInstallDir" After="InstallValidate" />
</InstallExecuteSequence>
2. 设置安装目录
将目录DataDir的地址改到 C:\Documents and Settings\All Users\Application Data\MyProduct
<CustomAction Id="SetAppDataDir" Directory="DataDir" Value="[CommonAppDataFolder]MyProduct" />
<InstallExecuteSequence>
<Custom Action="SetAppDataDir" Before="InstallFiles" />
</InstallExecuteSequence>
3.执行脚本 VBScript 和 JScript
<CustomAction Id="testVBScript" Script="vbscript" Execute="immediate" >
<![CDATA[
msgbox "this is embedded code..."
msgbox "MyProperty: " & Session.Property("MyProperty")
]]>
</CustomAction>
<InstallUISequence>
<Custom Action="testVBScript" After="LaunchConditions" />
</InstallUISequence>
4.执行外部的 脚本
Sub myFunction()
msgbox "This comes from an external script"
End Sub
<Binary Id="myScriptVBS" SourceFile=".\myScript.vbs" />
<CustomAction Id="myScript_CA" BinaryKey="myScriptVBS" VBScriptCall="myFunction" Execute="immediate" Return="check" />
再插入队列 使用 延迟执行。
5.调用C#
-
先新建一个工程
-
定义一个方法
public class CustomActions { [CustomAction] public static ActionResult MyFunction(Session session) { string myProperty = session["myProperty"]; return ActionResult.Success; } }
-
编译之后 会有两个dll,使用后缀为.CA.dll的那个文件,不是直接用添加引用,而是要用Binary标签
<Binary Id="myCustomActionsDLL" SourceFile=".\myCustomActions.CA.dll" />
-
然后用BinaryKey 和 DllEntry 去调用
<CustomAction Id="CA_myCustomAction" BinaryKey="myCustomActionsDLL" DllEntry="MyFunction" Execute="deferred" Return="check" />
注意在一个程序集 最多只能有16个方法。
6 触发一个可执行程序
-
第一种方法,使用Binary 先将程序存储起来
<Binary Id="myProgramEXE" SourceFile="$(sys.SOURCEFILEDIR)myProgram.exe" /> <CustomAction Id="myProgramEXE_CA" BinaryKey="myProgramEXE" Impersonate="yes" Execute="deferred" ExeCommand="" Return="check" />
- Impersonate 为 no 则以本地用户运行 , 为yes 则以安装用户执行。
- ExeCommand 是放的cmd语句。若要执行exe 这个属性是必须存在的,即使为空。
再加入队列
这个问题是卸载的时候也会执行一边。岂不是蛋疼?
-
第二种方法 就是将可执行程序copy到用户端去
<DirectoryRef Id="INSTALLLOCATION"> <Component Id="CMP_MainAppEXE" Guid="7AB5216B-2DB5-4A8A-9293-F6711FFAAA83"> <File Id="mainAppEXE" Source="MainApp.exe" KeyPath="yes" /> </Component> </DirectoryRef>
然后使用FileKey
<CustomAction Id="RunMainApp" FileKey="mainAppEXE" ExeCommand="" Execute="commit" Return="ignore" />
Execute=“commit” 的用意就是只有安装成功才会运行这个Action
同样可以使用ExeCommand 来执行
<CustomAction Id="RunMainApp" Directory="INSTALLLOCATION" ExeCommand="[INSTALLLOCATION]Main_App.exe" Execute="commit" Return="ignore" />
这个正常,卸载的时候不会再次触发
7.发出一个错误 阻止安装
<CustomAction Id="ErrorCA" Error="Ends the installation" />
<InstallUISequence>
<Custom Action="ErrorCA" Before="ExecuteAction">
<![CDATA[ myProperty <> "1" ]]>
</Custom>
</InstallUISequence>
action 也可以回滚
<CustomAction Id="systemChangingCA" Execute="deferred" Script="vbscript">
msgbox "Imagine this changes the system in some way"
</CustomAction>
<CustomAction Id="myRollbackCA" Execute="rollback" Script="vbscript">
msgbox "Imagine this undoes the changes"
</CustomAction>
<CustomAction Id="causeError" Execute="deferred" Script="vbscript">
return failure
</CustomAction>
插入序列
<InstallExecuteSequence>
<Custom Action="myRollbackCA" Before="systemChangingCA" />
<Custom Action="systemChangingCA" After="InstallInitialize" />
<Custom Action="causeError" After="systemChangingCA" />
</InstallExecuteSequence