之前看了好幾個打包軟件 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