一、背景
之前寫過的幾個WPF
小工具,每次發布都需要給它打安裝包和升級包,涉及到一些系列繁瑣的手工操作,有了Power Automate Desktop
,於是便尋思着能不能做成一個自動化的流來使用。
二、創建流任務
創建名為創建WPF程序安裝包及升級包
的流任務。
三、添加主流程
因為整個步驟比較長,為了更好的設計整個流,我們將這次流拆成幾個子流程,然后通過主流程串起來。
3.1 設置WPF項目目錄位置SettingProjectDir
1. 顯示選擇文件夾對話框,彈窗交互選擇當前WPF項目所在的文件夾,我們用名為CurrentProjectDir
變量來存儲它,如果是常用位置,我們還可以設置默認值。
3.2 設置WPF項目存檔位置SettingArchiveDir
1. 顯示選擇文件夾對話框,彈窗交互選擇安裝包和升級包的存檔位置,我們用名為CurrentArchiveDir
變量來存儲它,如果是常用位置,我們還可以設置默認值。
3.3 設置變量,設置WPF項目起始子項目名稱ProjectStartDir
1. 設置變量,變量名ProjectStartDir
,用來存儲WPF項目的起始子項目名稱,方便我們后續找到正確的起始入口。
大家都知道,一般來說我們在一個解決方案中會構建多個子項目,所以我們這里需要知道在CurrentProjectDir
中入口子項目是哪個,也就是包括App.xaml
的那個項目。
3.4 獲取當前程序版本號GetAppVersion
0. 概覽
1. 設置變量,變量名StartAssemblyFilePath
,拼接出ProjectStartDir
的AssemblyInfo.cs
文件位置。
%CurrentProjectDir%\%ProjectStartDir%\Properties\AssemblyInfo.cs
這個信息中,存儲了程序版本號等基礎信息。
2. 從文件讀取文本,從StartAssemblyFilePath
中讀取文本到變量StartAssemblyContents
中。
3. 分析文本,從StartAssemblyContents
中正則匹配出版本號信息,將結果存儲到MatchAssemblyContents
變量。
"[0-9.]+"
但是遺憾的是,這里得到的結果是帶了雙引號的數據,比如: "1.0.0.0"
4. 拆分文本,從MatchAssemblyContents
中我們通過拆分文本來提取最終我們要的版本號,通過自定義分隔符的模式,用分隔符"
來進行分割,分割結果放在變量SplitAssemblyContents
中。
5. 設置變量,從SplitAssemblyContents
結果中,提取第二個位置的數據,就是我們要的版本號,將版本號存在變量CurrentAppVersion
中。
%SplitAssemblyContents[1]%
這樣我們就可以得到我們要的最終數據1.0.0.0
3.5 獲取當前環境模式GetEnvMode
0. 概覽
1. 設置變量,變量名AppSettingsFilePath
,拼接出ProjectStartDir
的AppSettings.json
文件位置。
%CurrentProjectDir%\%ProjectStartDir%\appsettings.json
這個信息中,存儲了程序本地應用配置信息。
2. 從文件讀取文本,從AppSettingsFilePath
中讀取文本到變量AppSettingsContents
中。
這里留意AppSettingsContents
的內容通常是JSON
格式的。
{
"ThirdHostConfig": {
"HostAddress": "http://gateway.xxxxxxx.com",
"CallModel": "GateWay"
}
}
3. 將JSON轉換為自定義對象,將AppSettingsContents
內容以JSON
對象的形式提取出來,存儲到變量AppSettingsJsonObj
。
4. 設置變量,從AppSettingsJsonObj
中提取網關地址,存儲為變量CurrentGatewayUrl
。
%AppSettingsJsonObj.ThirdHostConfig.HostAddress%
JSON
對象的數據,在Power Automate
中可以直接用.
來逐層獲取值,非常方便。
5. 設置變量,變量名為CurrentEnvMode
來存儲,當前環境模式。
設置一個初始值為UnKnown
。
UnKnown
6. Switch-Case,根據CurrentGatewayUrl
的特征,來識別對應的CurrentEnvMode
值。
以其中一個Case
為例,我們選擇運算符為包含
,把特征值寫在要比較的值
中,並且可以設置忽略大小寫
。
最終,通過多個Case的組合我們得到一個完整的提取CurrentEnvMode
值的流程。
運算符 | 要比較的值 | 結果值 |
---|---|---|
包含 | xxxx-dev |
DevC1 |
包含 | gwkbs |
DevC1 |
包含 | gxxdev |
Dev |
包含 | gwdev |
Dev |
包含 | gxxfat |
Fat |
包含 | gwfat |
Fat |
包含 | gxxuat |
Uat |
包含 | gwfat |
Uat |
包含 | gatewayxx |
Pro |
3.5 創建WPF安裝包CreatePackage
0. 概覽
1. 設置變量,變量名VisualStudioEnvDir
,設定當前系統安裝的Visual Studio
版本對應的IDE目錄位置
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\Common7\IDE
2. 設置變量,變量名InstallerProjectPath
, 設定CurrentProjectDir
中Visual Studio Installer Project
的相對位置。
Setup1\Setup1.vdproj
3. 運行PowerShell腳本,來執行調用devenv.com
命令,進行對Visual Studio Installer Project
編譯,得到安裝包,這一步我們命名為BuildInstallProject
。
cd '%VisualStudioEnvDir%'
.\devenv.com '%CurrentProjectDir%\%InstallerProjectPath%' /rebuild "Release|Any CPU"
- 我們先切換到
VisualStudioEnvDir
這個目錄,因為我們需要到當前系統安裝的Visual Studio
版本對應的IDE目錄,去調用devenv.exe
; - 這里使用
.\devenv.com
,而不是.\devenv.exe
; - 隨后跟的是指定的
.vdproj
文件的完整路徑,也就是說指定是對這個Visual Studio Installer Project
進行處理; /rebuild
是devenv
的一個參數,代表先清理后編譯生成指定的項目或者解決方案,如果不需要清理,使用/build
命令也是可以的;"Release|Any CPU"
代表以Release
模式進行生成,並且針對的設備平台是Any CPU
;
如果順利的話,最終根據這個命令可以得到.msi
的安裝包。
上述命令,建議先在終端中驗證一下,單獨在終端中執行效果如下圖:
如果遇到下面這個錯誤,繼續看下面的解決辦法。
ERROR: An error occurred while validating. HRESULT = '8000000A'
官方給出了一個快捷的解決辦法,只要是Visual Studio 2017+
,都可以使用這個方法。
找到當前系統安裝的Visual Studio
版本對應的DisableOutOfProcBuild
目錄。
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\Common7\IDE\CommonExtensions\Microsoft\VSI\DisableOutOfProcBuild
在地址欄,輸入cmd
,以快速進入這個目錄的當前終端上下文,然后執行如下命令即可。
DisableOutOfProcBuild.exe
這個執行之后,實際上是它為我們創建或者修改了已存在的一個注冊表項,以便解決前面的那個報錯。
4. 設置變量,變量名InstallerProductName
, 設定安裝包產品名稱。
5. 設置變量,變量名InstallerPackagePath
, 提取最終的.msi
安裝包路徑。
%CurrentProjectDir%\Setup1\Release\%InstallerProductName%.msi
6. 設置變量,變量名InstallerVersionName
,拼接出按版本號命名的文件名。
%CurrentEnvMode%-%InstallerProductName%-v%CurrentAppVersion%
最終得到的是比如是:Dev-xxxxx-v1.0.0.0
7. 重命名文件,將InstallerPackagePath
文件重命名為InstallerVersionName
,得到按版本號命名的新安裝包,這個動作我們叫RenamePackageFile
8. 設置變量,變量名InstallerPackageFilePath
, 拼接出按版本號命名的新文件名。
%CurrentProjectDir%\Setup1\Release\%InstallerVersionName%.msi
參考
- 使用devenv在命令行中編譯項目
- How to build visual studio installer project (.vdproj) from jenkins to generate .exe and .msi files?
- An error occurred while validating. HRESULT = '8000000A'
- Visual Studio Installer 部署
- .Net5 WPF快速入門系列教程