之前看了好几个打包软件 advanceinstaller installshield什么的, 发现大都是收费的, 看的Wix还是sourceforget上停更的版本, 以为没戏, 没想到在github偶尔看到了WixToolSet,原来还有更新, 还有VS2019的插件,赶紧下了一个用用.终于把我的dotnetcore网站打包成msi了.
下面就是wix的封装脚本.wxs文件. 要安装的东西用一个Component元素表示, 因为是网页, 引用项目的话也拿不到他的发布路径(publishurl),所以我这里就都做成rar包了, 安装过程就是把Rar包放到客户电脑上,再通过CustomAction执行bat脚本, 脚本调用rar.exe进行文件解压. 然后使用nssm将core网站注册为windows服务,mysql数据库也是同理. 卸载前则需要执行脚本像将注册的网站和mysql服务删除掉,卸载的脚本需要等待完成才能执行文件删除,所以action里是 Return="ignore",执行bat不知道怎么返回成功,所以得用ignore, 如果用了check就会变成卸载事故,无法卸载了(别问我是怎么知道的)...
安装程序的风格用的是 <UIRef Id="WixUI_InstallDir"/> 表示只有license声明和修改安装路径两大界面.
声明的文本在这句里<WixVariable Id="WixUILicenseRtf" Value="license.rtf" />
然后安装路径界面把路径传入一个属性Property里,这个元素的id要求是WIXUI_INSTALLDIR, 他的Value这是目录声明的Directory的id
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
然后整个安装包只有msi没有cab文件靠的是这一句 <MediaTemplate EmbedCab="yes" />
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="CF9E5738-6F16-471E-8937-367ACA75D5E0" Name="AIWebSetup" Language="2052" Codepage="936" Version="1.0.0.1" Manufacturer="HrstAi" UpgradeCode="cdf0d953-c5f0-4b27-8ea3-4da1fab43252">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<Feature Id="ProductFeature" Title="AIWebSetup" Level="1">
<ComponentRef Id="serviceAction" />
</Feature>
<WixVariable Id="WixUILicenseRtf" Value="license.rtf" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
<UIRef Id="WixUI_InstallDir"/>
<CustomAction Id='LaunchFile1' Impersonate="no" ExeCommand="[SystemFolder]cmd.exe /k initiate.bat" Directory="INSTALLDIR" Return="asyncWait"/>
<CustomAction Id='LaunchFile2' Impersonate="no" ExeCommand="[SystemFolder]cmd.exe /k uninstall.bat" Directory="INSTALLDIR" Return="ignore"/>
<InstallExecuteSequence>
<Custom Action='LaunchFile2' Before="RemoveFiles">
(REMOVE~="ALL") AND (NOT UPGRADINGPRODUCTCODE)
</Custom>
<Custom Action='LaunchFile1' After='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="AIDetect" >
<Directory Id="website" Name="website" />
<Directory Id="mysql" Name="aimysql" />
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="INSTALLDIR">
<Component Id="serviceAction" Guid="8965BDD3-FA71-4E5D-9C67-75A4B87920B0" Win64="no">
<File Id="nssm.exe" Source="content/nssm.exe" />
<File Id="sed.exe" Source="content/sed.exe" />
<File Id="mysql57.rar" Source="mysql/mysql57x64.rar" />
<File Id="website.rar" Source="website/website.rar" />
<File Id="rar.exe" Source="content/rar.exe" />
<File Id="initiate.bat" Source="content/initiate.bat" />
<File Id="uninstall.bat" Source="content/uninstall.bat" />
</Component>
</DirectoryRef>
</Fragment>
</Wix>
mysql压缩包解压后 调用 mysqld install 就能注册服务并启动, 调用mysqld remove 则把服务删除,非常方便.可以把自己的空数据和改好的数据库密码先弄好再打成压缩包, 就不用执行初始化sql脚本了.
nssm注册服务则需要找到 客户的dotnetcore安装路径(在cmd 输入 where dotnet 就能获取到了(可能有32和64两个位置)).
安装bat如下
@echo off
set curpath=%~dp0
for /F "tokens=*" %%i in ('where dotnet ') do (
set exepath=%%i
echo %exepath% | findstr "x86" && echo yes || goto rar
)
goto end
:rar
echo It is extracting files now, please wait...
"%curpath%rar" x -y -inul "%curpath%mysql57x64.rar" "%curpath%aimysql\"
del /q/f "%curpath%mysql57x64.rar"
"%curpath%rar" x -y -inul "%curpath%website.rar" "%curpath%website\"
del /q/f "%curpath%website.rar"
goto sqlcheck
:sqlcheck
set port=13360
netstat -ano|findstr :%port%
if ERRORLEVEL 1 (goto sqlok) else (goto sqlerr)
:sqlok
"%curpath%aimysql\bin\mysqld" install aidmysql --port=%port%
net start aidmysql
goto web
:sqlerr
echo please input your mysql password
set /p sqlpwd=
"%curpath%aimysql\bin\mysql" -uroot -p%sqlpwd% <"%~dp0website\dbscript\create_table.sql"
"%curpath%aimysql\bin\mysql" -uroot -p%sqlpwd% <"%~dp0website\dbscript\init_data.sql" --default-character-set utf8
if ERRORLEVEL 1 (goto end) else (goto pwdChange)
:pwdChange
sed -i s/pwd=Asdf1234;/pwd=%sqlpwd%;/g "%~dp0website\appsettings.json"
goto web
:web
set webport=11000
netstat -ano|findstr :%webport%
if ERRORLEVEL 1 (goto webservice) else (goto weberr)
:weberr
echo please input your website port
set /p webport=
netstat -ano|findstr :%webport%
if ERRORLEVEL 1 (goto webport) else (goto weberr)
:webport
sed -i s/http:\/\/\*:11000/http:\/\/\*:%webport%/g "%~dp0website\appsettings.json"
goto webservice
:webservice
"%curpath%nssm" install aidweb "%exepath%"
"%curpath%nssm" set aidweb AppDirectory "%~dp0website"
"%curpath%nssm" set aidweb AppParameters Hrst.AIDetect.PCWeb.dll
"%curpath%nssm" start aidweb
goto firewall
:firewall
netsh advfirewall firewall add rule name="aidfw" dir=in program="%exepath%" action=allow
echo the website url is http://localhost:%webport%
goto end
:end
echo install sucess
在网上找到了关于Wix 的书 <<wix cookbook>>
网盘 https://pan.baidu.com/s/1-ibGJHtq0CPfYyKlCjqCHg
提取码 egmx