WiX# 是一个强大的工具集,它允许开发者创建MSI和EXE安装程序,执行不仅仅是运行可执行文件和复制文件的操作。通过自定义动作(CustomAction),可以编写各种形式的动作,用于在升级过程中备份和恢复应用程序设置、设置先决条件或向远程服务器报告安装等任务。
本文将介绍如何使用WiX#创建一个安装Apache Tomcat作为Windows服务的安装脚本,这是通过自定义动作实现的。
WiX# 工具集允许MSI和EXE安装程序执行更多操作。自定义动作允许编写各种形式的动作,例如在升级过程中备份和恢复应用程序设置、设置先决条件或向远程服务器报告安装等。
在继续之前,将做一些假设。如果这些假设不成立,体验可能会有所不同。
在这个场景中,需要从MSI安装一个先决条件,例如Apache Tomcat,而不是从引导程序安装。这与使用引导程序安装的方式有所不同。
private static string BuildMsi() {
var TestDir = new Dir(@"%ProgramFiles%\My Company\My Product");
TestDir.Files = System.IO.Directory.GetFiles(@"D:\Checkouts\WixSharp Tutorial\WixSharp Tutorial\SampleApp\bin\Release").Where(file => file.EndsWith(".dll") || file.EndsWith(".exe")).Select(file => new File(file)).ToArray();
var project = new Project("MyProduct", TestDir);
project.GUID = new Guid("6fe30b47-2577-43ad-9095-1861ba25889b");
project.SourceBaseDir = "";
project.OutDir = "
注意上面在代码中添加了一个新的部分。
project.Action添加了一系列可以以多种方式定义的动作。WiX的方式主要是vbs或Jscript,但对于.NET开发者来说,Managed Actions会更熟悉,维护起来也更容易。在下面的单独类中定义了这些动作。
以下是如何实现自定义动作的代码示例,例如上面的动作。
public class CustomActions {
[CustomAction]
public static ActionResult CheckForApache(Session session) {
ActionResult result = ActionResult.Success;
try {
System.ServiceProcess.ServiceController apache = ServiceController.GetServices().FirstOrDefault(s => s.ServiceName == "Tomcat8");
if (apache == null) {
if (System.IO.File.Exists(@"C:\ProgramData\chocolatey\choco.exe")) {
CmdRunner(@"@"" %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe"" - NoProfile - InputFormat None - ExecutionPolicy Bypass - Command ""iex((New - Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))"" && SET ""PATH =% PATH %;% ALLUSERSPROFILE%\chocolatey\bin"");
CmdRunner("Choco install Tomcat");
}
}
} catch {
result = ActionResult.Failure;
}
return result;
}
public static void CmdRunner(string cmd) {
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C" + cmd;
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
}
}
上面的代码有几个问题。强迫用户安装Chocolatey(Windows的包管理器),检查默认的服务名称,安装了一个作为安装程序可用的先决条件(这里)。这意味着应该在引导程序中捆绑它。
Wix#自定义动作有多种口味,如在github上展示的,但ManagedAction和ElevatedManagedAction对.NET开发者来说更容易处理。
自定义动作可以比上面展示的更多。例如,如果想在安装后立即启动应用程序怎么办?
new InstalledFileAction("sample_exe", "", Return.asyncNoWait, When.After, Step.InstallFinalize, Condition.NOT_Installed),
这表明这个MSI安装的文件将在InstallFinalizes之后运行,并且即使安装程序退出,它也会继续运行,但前提是应用程序尚未安装。