背景
最近用WPF开发一个桌面版程序,连接的是mysql。
需要用到mysql-connector。
用VS的Visual Studio Installer制作安装包时,发现只是把mysql-connector-net-6.9.11.msi安装后的dll打包进安装包是不够的。需要在安装目标机器上也安装有mysql-connector-net-6.9.11.msi 才行。
mysql-connector-net-6.9.11.msi安装后的dll目录
(C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.11\Assemblies\v4.5)
这样就遇到一个问题,如何把mysql-connector-net-6.9.11.msi 和 我的WPF程序安装包 一块 同步进行安装和卸载。
解决方法
调查发现,需要使用Install Shield这个第三方程序打包工具。
-
我下了个 Install Shield2020 R1 Premier版本,网上有破解版本。搜一个破解以下就行。
https://www.jb51.net/softs/726885.html -
不要把Install Shield连接VS 使用,会要求重新激活。
直接点击菜单栏的【Install Shield 2020】打开下面这样的窗口就行。
-
新建一个【Basic MSI】或者【InstallScript MSI】的项目。最好是【InstallScript MSI】,【Basic MSI】好像在卸载时,不会执行编写的install script。
-
在 【BEHAVIOR AND LOGIC】→【InstallScript】→ 【Files】→【Setup.Rul】下记入下面代码。
//===========================================================================
//
// File Name: Setup.rul
//
// Description: Blank setup main script file
//
// Comments: Blank setup is an empty setup project. If you want to
// create a new project via. step-by step instructions use the
// Project Assistant.
//
//===========================================================================
// Included header files ----------------------------------------------------
#include "ifx.h"
// Note: In order to have your InstallScript function executed as a custom
// action by the Windows Installer, it must be prototyped as an
// entry-point function.
// The keyword export identifies MyFunction() as an entry-point function.
// The argument it accepts must be a handle to the Installer database.
/* export prototype MyFunction(HWND); */
export prototype MyFunction(HWND);
function MyFunction(hMSI)
// To Do: Declare local variables.
STRING svMsiexec, svParam, svMsiPackage, szSupportDir, sRegPathConnector, sRegPathProduct, sRegPathProduct64;
NUMBER nLength;
begin
MessageBox("This is MyFunction", 0);
// 安装命令
svMsiexec = WINSYSDIR ^ "msiexec.exe";
// mysql-connector的注册表路径
sRegPathConnector="SOFTWARE\\Classes\\Installer\\Products\\D5BFB7804F8F12947A982CC66523E434";
sRegPathProduct64="SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\\"^PRODUCT_GUID;
sRegPathProduct="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"^PRODUCT_GUID;
MessageBox(sRegPathProduct, 0);
// 安装文件的路径
MsiGetProperty(hMSI, "SUPPORTDIR", szSupportDir, nLength);
svMsiPackage = szSupportDir ^ "mysql-connector-net-6.9.11.msi";
LongPathToQuote(svMsiPackage, TRUE);
MessageBox(svMsiPackage, 0);
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
// 安装时
if (RegDBKeyExist(sRegPathProduct) < 0 && RegDBKeyExist(sRegPathProduct64) < 0) then
MessageBox("This is INSTALL status", 0);
//监测Mysql connector是否安装
if(RegDBKeyExist(sRegPathConnector) < 0) then
MessageBox("mysql-connector未安装",INFORMATION);
// 安装参数
svParam = "/i " + svMsiPackage+" /qb";
// 先静默安装Mysql connector,/qb表示基本的提示界面
LaunchAppAndWait(svMsiexec,svParam,WAIT);
//MessageBox("LaunchAppAndWait", INFORMATION);
// 执行Mysql connector安装
//svParam = "/f " + svMsiPackage;
//if(LaunchAppAndWait(svMsiexec,svParam,LAAW_OPTION_WAIT) < 0) then
// MessageBox("安装mysql-connector失败",INFORMATION);
//endif;
else
//MessageBox("mysql-connector已经安装",INFORMATION);
endif;
else
MessageBox("This is UNINSTALL status", 0);
// 卸载时
// 检查Mysql connector是否已经安装
if(RegDBKeyExist(sRegPathConnector) >= 0) then
MessageBox("mysql-connector已安装",INFORMATION);
// 卸载参数
svParam = "/uninstall " + svMsiPackage+" /qb";
// 卸载Mysql connector,/qb表示基本的提示界面
LaunchAppAndWait(svMsiexec, svParam, WAIT);
endif;
endif;
end;
- 在【BEHAVIOR AND LOGIC】→【Custom Actions and Sequences】→【Custom Actions】里面新建一个Action。
【Install UI Sequence】设置为【After ISSetupFilesExtract】。
【In-Script Execution】设置为【Immediate Execution】。
- 需要添加一个【Support FIles】。
把【mysql-connector-net-6.9.11.msi】添加进去,供 Install Script 使用。
// 安装文件的路径
MsiGetProperty(hMSI, "SUPPORTDIR", szSupportDir, nLength);
svMsiPackage = szSupportDir ^ "mysql-connector-net-6.9.11.msi";
- 其他的参照其他的普通操作手册 就可以。
问题
-
Install Script中判断是安装还是卸载
有的参考网址上说,可以使用【MsiGetProperty(hMSI, “REMOVE”, sRemove, nBuffer)】,不过在 【After ISSetupFilesExtract】这个节点,REMOVE好像没有值。
我使用的是 利用PRODUCT_GUID查询注册表的方式,如果注册表中已经有"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" 了, Install Script中 就 当成卸载,没有考虑修复安装 这种情况。 -
主程序真正的安装过程中是 不能进行 其他msi程序的安装或卸载的。因此,【After ISSetupFilesExtract】时点的选择很重要。
-
通过开始菜单上的,uninstall 卸载程序是没有问题的。
如果重新点击 setup.exe,会弹出 修复或除去的 对话框,这个对话框之前 就已经进行了 【mysql-connector-net-6.9.11.msi】的卸载,这是个问题。如何 识别是真正卸载时,才去卸载 【mysql-connector-net-6.9.11.msi】。
参考
https://www.cnblogs.com/zhengshuangliang/p/13653611.html
https://blog.csdn.net/weixin_30371469/article/details/95889377