有时候我们需要在程序中执行另一个程序的安装,这就需要我们去自定义msi安装包的执行过程。
比如我要做一个安装管理程序,可以根据用户的选择安装不同的子产品。当用户选择了三个产品时,如果分别显示这三个产品的安装交互UI显然是不恰当的。我们期望用一个统一的自定义UI去取代每个产品各自的UI。
平时使用msiexec.exe习惯了,所以最直接的想法就是在一个子进程中执行:
msiexec.exe /qn
这样固然是能够完成任务,但是不是太简陋了? 安装开始后我们想取消这次安装怎么办? 或者我们还想要拿到一些安装进度的信息。
其实可以通过调用三个windowsAPI 轻松搞定这个事儿!下面的C# demo用一个自定义Form来指示多个MSI文件的安装过程。Form上放的是一个滚动条,并且配合一个不断更新的label。
下面是安装过程中的UI:
aaarticlea/png;base64,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/Kj31aHSUT7s1WEF8k8gmojJvfYnBZBd+qZEX9+U/9JZAgmMHAKZYkeP9fluxVvb4WhxYQSQGfUSQ7IIHEvYpG91P/2lIKzzwwGFZZJAPwLy1vU5vah1j0aFPBQZRj4BFUDlcq8darnWL2c2CqCRf9fZwnwQSBc4+lnKtALp+fQ0WodCPf/zLoC0YcayI5avQE8Ajixix4Lem1YiMoFYabglgUIT6Ep0Y0HF4TjUvz9Ewhe6eJY3DAT0O5ve6zKbF5F4VOaxZvNdHIaKsUgSKEEC6c9z3beOrf30rTZPNYMllPLZ3LwLIFVyNvn21NnRiTWrVsPjccMhY+rawPRXMh2HwfJ5s5n3nhNwyHtYPEH4INxzhCV1pdp7VPS0JLZT+pTUnWNli41ANrGj4sZ66XlrPxaL9QqfcDhstEI+25N3ARSNijNhVSXmzTu4tx3p5q30/d4E3CEBEiABEiABEhixBCxhlN7A9DjVBk6nE6oh8hXyLoC04mrx0YZoSG+gieAfEiABEiABEiABEhAC6UaRfA+DFUQAqeih8OF7mwRIgARIgARIIBeBQmoFTm3IdSd4jgRIgARIgARIYEQSoAAakbeVjSIBEiABEiABEshFgAIoFx2eIwESIAESIAESGJEEKIBG5G1lo0iABEiABEiABHIRoADKRYfnSIAESIAESIAERiQBCqAReVvZKBIgARIgARIggVwEKIBy0eE5EiABEiABEiCBEUmAAmhE3lY2igRIgARIgARIIBcBCqBcdHiOBEiABEiABEhgRBKgABqRt5WNIgESIAESIAESyEWAAigXHZ4jARIgARIgARIYkQQogEbkbWWjSIAESIAESIAEchGgAMpFh+dIgARIgARIgARGJAEKoBF5W9koEiABEiABEiCBXAQogHLR4TkSIAESIAESIIERSYACaETeVjaKBEiABEiABEggFwEKoFx0eI4ESIAESIAESGBEEqAAGpG3lY0iARIgARIgARLIRYACKBcdniMBEiABEiABEhiRBCiARuRtZaNIgARIgARIgARyEXDmOjnU5xKJBNxuN7xe76CyDofDCAaDsNlsJr1e7/P5oNv0+FyZaVq/349IJALNz8rLuqasrAyhUAgej8dso9Fobxq9TstJj7Ou45YESIAESIAESKB0CRRUALlcLmzcuBHvvPNOLzEVKCo+HA4Henp6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" alt="" />
点击Cancel按钮取消安装后的UI:
aaarticlea/png;base64,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X6+aKgIiIAIiIAJFTKAg4scTPlxS9HjiZ6QUXRHzVtVEQAREQAREQARGmcCwi59cgZMrfka5nTq8CIiACIiACIhAkRMYqV6iYRc/HtdcETRSjfGOraUIiIAIiIAIiIAIDESgYOJnoAMqXgREQAREQAREQARGk8BBi59BPfDN10dBBERABDSMTWAAAB8gSURBVERABERABIqNwEGLH68h/acIVxeXR0ZLERABERABERCBYiRwyOLHNWoAIw+FkMRQMZ521UkEREAEREAEDl8C9h3cHOWSMxkkV72/wxePWi4CIiACIiACIlBqBGz2Qe9DYjkiqNRaqfaIgAiIgAiIgAiIQJaAWX76hhzjT98d2hIBERABERABERCBEiBgPj80/dD6UwKtURNEQAREQAREQAREYBAC/Ryeze4j088gyLRbBERABERABERgLBNwPj9juQGquwiIgAiIgAiIgAgcCIGgS9zH4EPTj/d3IEUprQiIgAiIgAiIgAgUP4F+3V7FX2HVUAREQAREQAREQAQOhYA/M9bdivAN5OyTiR9o76EcXHlFQAREQAREQAREYKQJZH1+TNp46kajvkb6HOh4IiACIiACIiACI0jAn0ql9gqfETywDiUCIiACIiACIiACo0EgiHTW5JNj8fGMQLlfvhiNyumYIiACIiACIiACIjDcBMzhmV1e2b/evq/hPozKEwEREAEREAEREIHiIJB3tFeOEag4aqlaiIAIiIAIiIAIiMAwEfD7+F0LjvTqVTzpHPtPbwfYMB1OxYiACIiACIiACIjA6BIwy0+v6umtifvOV7/ofpu9abUiAiIgAiIgAiIgAmOJgD9lqibd/6umMviMpXOouoqACIiACIiACBwAARM/pn58NAB5tp3s0gkgL24oJe5N67rShpJFaURABERABERABERghAkEQ4EUkublY7P9uA4wX/bfpC/V2yE2mCGIsic3TdobPm/xbh4hW/ptLmkFERABERCBQyOQe689tJKUWwSKjwD1w0gYUEz8JJBKZ6w2FD4+W0+n/UiY+KFcyWxn9w/4CQzPcMS85jCdrTwbQPHDpcRP8f3IVCMREIGxQsDdna2yPgR6X0vHSt1Vz4MlEOczubdX5mBLUb58BIKmsfLFDxCbN+mwRupEDytOFSYCIlAKBOw2HQmEEQxWojJYUQotUhuGQCCJBKKBiLMulMqzMbdnKB8CGkoGS5Mv34HGBQ80QyHSeyeVS2+9EMdRmSIgAiIwJgn40ygPlqMuUo+6YNWYbIIqfeAE/IEAKuy8sxumVHpPvN4h0hgJkTMQ9VEVP57Q8Zae4vO2cyudLy53v9ZFQAREoFQJ+P0B86tMI5lOmI9mslSbqXb1I8DzzfPut0FJY1X8eALHW7IddIfhtvdc9/ax+bnr/XAM6+aIiB82MGAK1msoW8B1/uUCyN3fv5X729c/rbZFQAREoJQIxH0JLKk9zt1Ho37rBlE4LAh0p3pwbOV88PzzGToWQz4xk2vo8PyCvXTekm31dEIh2j0i4qerqwubN292ytVrTL6l19h8DZX4yUdFcSIgAocDAT4Q5gaOwDFlc0bszfhw4FrsbeRzryfeg40vb6Lrc7FXN2/9csUME3jbXHoWIC8+Xxz1QyFCQcUPGxKJRNDU1NQ76osnk6rPEzO5S289X0P3ty9fesWJgAiIQKkQ4P2vJx1DTzJWKk1SOw6AALu9SiXwt0xtkPtM5zYDl55ViOv8mzhxIsLhcK9oGi4OBRU/VHWs9IwZMwasr9foARNohwiIgAiIgAiIQMkRyBVA+2tcMmmzEWYF0v7SHci+goofVoQVTiQSB1InpRUBERABERABERCBghEoHVtawRCpYBEQAREQAREQgVIiIPFTSmdTbREBERABERABERiUgMTPoIiUQAREQAREQAREoJQISPyU0tlUW0RABERABERABAYlIPEzKCIlEAEREAEREAERKCUCEj+ldDbVFhEQAREQAREQgUEJSPwMikgJREAEREAEREAESomAxE8pnU21RQREQAREQAREYFACEj+DIlICERABERABERCBUiIg8VNKZ1NtEQEREAEREAERGJSAxM+giJRABERABERABESglAhI/JTS2VRbREAEREAEREAEBiUg8TMoIiUQAREQAREQAREoJQISP6V0NtUWERABERABERCBQQlI/AyKSAlEQAREQAREQARKiYDETymdTbVFBERABERABERgUAISP4MiUgIREAEREAEREIFSIiDxU0pnU20RAREQAREQAREYlIDEz6CIlEAEREAEREAERKCUCEj8lNLZVFtEQAREQAREQAQGJSDxMygiJRABERABERABESglAsGRakw6nUYoFEJFRcWQDsn0LS0t8Pl8Lj23o9EoIpFI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" alt="" />
先看一下这三个API:
[DllImport("msi.dll", CharSet = CharSet.Auto)]
internal static extern int MsiSetInternalUI(int dwUILevel, IntPtr phWnd);
在调用msiexec.exe时,我们通过指定 /q参数让安装过程显示不同的UI。如果不显示UI的话就要使用参数 /qn 。MsiSetInternalUI方法就是干这个事儿的。通过下面的调用就可以去掉msi中自带的UI:
NativeMethods.MsiSetInternalUI(2, IntPtr.Zero)
[DllImport("msi.dll", CharSet = CharSet.Auto)]
internal static extern MsiInstallUIHandler MsiSetExternalUI([MarshalAs(UnmanagedType.FunctionPtr)] MsiInstallUIHandlerpuiHandler, NativeMethods.InstallLogMode dwMessageFilter, IntPtr pvContext);
MsiSetExternalUI 函数允许指定一个用户定义的外部UI handler用来处理安装过程中产生的消息。这个外部的UI handler会在内部的UI handler被调用前调用。 如果在外部的UI handler中返回非0的值,就说明这个消息已经被处理。
这个外部的UI handler就是MsiSetExternalUI方法的第一个参数,我们通过实现这个handler来处理自己感兴趣的消息, 比如当安装进度变化后去更新进度条。或者通过它传递我们的消息给msi,比如说告诉msi,停止安装,执行cancel操作。使用这个方法需要注意的是,当你完成安装后一定要把原来的handler设回去。否则以后执行msi安装包可能会出问题。
MSDN上有一个MsiInstallUIHandler 的demo,感兴趣的同学可以看看。
[DllImport("msi.dll", CharSet = CharSet.Auto)]
internal static extern uint MsiInstallProduct([MarshalAs(UnmanagedType.LPWStr)] string szPackagePath,[MarshalAs(UnmanagedType.LPWStr)] string szCommandLine);
正如其名,这个是真正干活儿的方法。
实在忍不住要介绍第四个方法,虽然它对实现当前的功能来说是可选的,但对一个产品来说,它却是用来救命的。
[DllImport("msi.dll", CharSet = CharSet.Auto)]
internal static extern uint MsiEnableLog(GcMsiUtil.NativeMethods.InstallLogMode dwLogMode,[MarshalAs(UnmanagedType.LPWStr)] string szLogFile, uint dwLogAttributes);
这个方法会把安装log保存到你传递给它的文件路径。有了它生活就会happy很多,很多… 否则当用户告诉你安装失败时,你一定会抓狂的。
好了,下面是MyInstaller demo的主要代码:
InstallProcessForm.cs
public partial class InstallProcessForm : Form
{
private MyInstaller _installer = null;
private BackgroundWorker _installerBGWorker = new BackgroundWorker();
internal InstallProcessForm()
{
InitializeComponent(); _installer = new MyInstaller(); _installerBGWorker.WorkerReportsProgress = true;
_installerBGWorker.WorkerSupportsCancellation = true; _installerBGWorker.DoWork += _installerBGWorker_DoWork;
_installerBGWorker.RunWorkerCompleted += _installerBGWorker_RunWorkerCompleted;
_installerBGWorker.ProgressChanged += _installerBGWorker_ProgressChanged; this.Shown += InstallProcessForm_Shown;
} private void InstallProcessForm_Shown(object sender, EventArgs e)
{
// 当窗口打开后就开始后台的安装
_installerBGWorker.RunWorkerAsync();
} private void _installerBGWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// 消息通过 e.UserState 传回,并通过label显示在窗口上
string message = e.UserState.ToString();
this.label1.Text = message;
if (message == "正在取消安装 ...")
{
this.CancelButton.Enabled = false;
}
} private void _installerBGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// 安装过程结束
} private void _installerBGWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bgWorker = sender as BackgroundWorker; // 开始执行安装方法
_installer = new MyInstaller();
string msiFilePath = "xxx.msi"; // msi file path
_installer.Install(bgWorker, msiFilePath);
} private void CancelButton_Click(object sender, EventArgs e)
{
_installer.Canceled = true;
_installerBGWorker.CancelAsync();
}
}
MyInstaller.cs
internal class MyInstaller
{
private BackgroundWorker _bgWorker = null; public bool Canceled { get; set; } public void Install(BackgroundWorker bgWorker, string msiFileName)
{
_bgWorker = bgWorker; NativeMethods.MyMsiInstallUIHandler oldHandler = null;
try
{
string logPath = "test.log";
NativeMethods.MsiEnableLog(NativeMethods.LogMode.Verbose, logPath, 0u);
NativeMethods.MsiSetInternalUI(2, IntPtr.Zero); oldHandler = NativeMethods.MsiSetExternalUI(new NativeMethods.MyMsiInstallUIHandler(MsiProgressHandler),
NativeMethods.LogMode.ExternalUI,
IntPtr.Zero);
string param = "ACTION=INSTALL";
_bgWorker.ReportProgress(0, "正在安装 xxx ...");
NativeMethods.MsiInstallProduct(msiFileName, param);
}
catch(Exception e)
{
// todo
}
finally
{
// 一定要把默认的handler设回去。
if(oldHandler != null)
{
NativeMethods.MsiSetExternalUI(oldHandler, NativeMethods.LogMode.None, IntPtr.Zero);
}
}
} //最重要的就是这个方法了,这里仅演示了如何cancel一个安装,更多详情请参考MSDN文档
private int MsiProgressHandler(IntPtr context, int messageType, string message)
{
if (this.Canceled)
{
if (_bgWorker != null)
{
_bgWorker.ReportProgress(0, "正在取消安装 ...");
}
// 这个返回值会告诉msi, cancel当前的安装
return 2;
}
return 1;
}
} internal static class NativeMethods
{
[DllImport("msi.dll", CharSet = CharSet.Auto)]
internal static extern int MsiSetInternalUI(int dwUILevel, IntPtr phWnd); [DllImport("msi.dll", CharSet = CharSet.Auto)]
internal static extern MyMsiInstallUIHandler MsiSetExternalUI([MarshalAs(UnmanagedType.FunctionPtr)]
MyMsiInstallUIHandler puiHandler,
NativeMethods.LogMode dwMessageFilter, IntPtr pvContext); [DllImport("msi.dll", CharSet = CharSet.Auto)]
internal static extern uint MsiInstallProduct([MarshalAs(UnmanagedType.LPWStr)] string szPackagePath,
[MarshalAs(UnmanagedType.LPWStr)]
string szCommandLine); [DllImport("msi.dll", CharSet = CharSet.Auto)]
internal static extern uint MsiEnableLog(NativeMethods.LogMode dwLogMode,
[MarshalAs(UnmanagedType.LPWStr)] string szLogFile,
uint dwLogAttributes); internal delegate int MyMsiInstallUIHandler(IntPtr context, int messageType,
[MarshalAs(UnmanagedType.LPWStr)] string message); [Flags]
internal enum LogMode : uint
{
None = 0u,
Verbose = 4096u,
ExternalUI = 20239u
}
}
简单说明一下,用户定义的UI运行在主线程中,使用BackgroundWorker执行安装任务。在安装进行的过程中可以把cancel信息传递给MsiProgressHandler,当MsiProgressHandler检测到cancel信息后通过返回值告诉msi的执行引擎,执行cancel操作(msi的安装过程是相当严谨的,可不能简单的杀掉安装进程了事!)。
这样,一个支持cancel的自定义UI的安装控制程序就OK了(demo哈)。如果要安装多个msi只需在Install方法中循环就可以了。
总结一下,通过调用几个windows API,我们可以实现对msi安装过程的控制。这比调用msiexec.exe更灵活,也为程序日后添加新的功能打下了基础。
感谢葡萄哥Nick 投稿