一、背景

之前写过的几个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,拼接出ProjectStartDirAssemblyInfo.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,拼接出ProjectStartDirAppSettings.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, 设定CurrentProjectDirVisual 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进行处理;
  • /rebuilddevenv的一个参数,代表先清理后编译生成指定的项目或者解决方案,如果不需要清理,使用/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

参考

Power Automate Desktop/RPA 爱好者交流群

流程自动化RPA,Power Automate Desktop系列 - 创建WPF程序安装包及升级包的更多相关文章

  1. 流程自动化RPA,Power Automate Desktop系列 - 不讲武德的Windows10内置应用

    简介 Power Automate Desktop 扩展Power Automate中的现有机器人流程自动化(RPA)功能,并使您能够自动化所有重复的桌面流程. 使用预生成的拖放操作或记录您自己的桌面 ...

  2. 流程自动化RPA,Power Automate Desktop系列 - 发布文档中心

    一.背景 内网中有一个基于VuePress搭建的静态文档中心,但是每次修改后都需要重新Build一次才行,之前都是手动执行命令,现在可以基于Power Automate Desktop来创建任务了. ...

  3. 流程自动化RPA,Power Automate Desktop系列 - DotNet Core打包并发布Nuget Package

    一.背景 DotNet Core通常基于Nuget来实现包管理,如果你想要把自己的实现共享给其他人,通常我们需要把本地项目打包好,然后发布到对应的Nuget Server上,以便于其他人可以查找.安装 ...

  4. 流程自动化RPA,Power Automate Desktop系列 - 批量备份Git仓库做好灾备

    一.背景 打个比如,你在Github上的代码库需要批量的定时备案到本地的Gitlab上,以便Github不能访问时,可以继续编写,这时候我们可以基于Power Automate Desktop来实现一 ...

  5. 流程自动化RPA,Power Automate Desktop系列 - 构建VuePress文档中心脚手架

    一.背景 笔者曾基于VuePress搭建过一个文档中心,但是在实现在线管理功能之前,很多时候,新建文档需要手动处理很多数据,看有没有可能实现一个脚手架来处理这些问题,所谓脚手架,就是进行文档初始化的一 ...

  6. 利用RTE创建自定义软件安装包(一)

    说明:鉴于MDK5.0推出的新功能,安富莱电子顺势推出几期MDK5.0新功能的使用方法.MDK5.0提供的RTE功能还是很不错的,这个功能一方面方便用户创建自己常用的驱动文件包,还有一个很重要的功能就 ...

  7. C++/CLI 创建WPF程序

    本文简单演示下用C++/CLI创建WPF程序,IDE为VS2015 首先创建CLR项目,选择CLR空项目: 然后,右键源文件,选择新建class,选择CLR->Component Class 接 ...

  8. WPF笔记1 用VS2015创建WPF程序

    使用WPF创建第一个应用程序.实现功能如下: 单击"Red"按钮,文本显示红色:单击"Black"按钮,文本显示黑色:单击"Back"按钮, ...

  9. 一文讲透为Power Automate for Desktop (PAD) 实现自定义模块 - 附完整代码

    概述 Power Automate for Desktop (以下简称PAD)是微软推出的一款针对Windows桌面端的免费RPA(机器人流程自动化)工具,它目前默认会随着Windows 11安装,但 ...

随机推荐

  1. GIT·版本回退的指令

    阅文时长 | 0.46分钟 字数统计 | 499.2字符 主要内容 | 1.引言&背景 2.指令集合&示例 3.声明与参考资料 『GIT·版本回退的指令』 编写人 | SCscHero ...

  2. SQLFlow数据流分析工具的job功能介绍

    SQLFlow是一款专业的数据血缘关系分析工具,在大型数据仓库中,完整的数据血缘关系可以用来进行数据溯源.表和字段变更的影响分析.数据合规性的证明.数据质量的检查等. 一.SQLFlow 是怎样工作的 ...

  3. python3 摆放家具练习

    摆放家具 需求: 1)房子有户型,总面积和家具名称列表 新房子没有任何家具 2)家具有名字和占地面积.其中: 床:占4平米 衣柜:占2平米 餐桌:占1.5平米 3)将以上三件家具添加到房子中 4)打印 ...

  4. .NET6系列:Visual Studio 2022 线路图

    系列目录     [已更新最新开发文章,点击查看详细] 在上一篇博客<Visual Studio 2022>中介绍了VS2022的性能改进与重要功能.本文主要介绍在 Visual Stud ...

  5. 域名更换为itwxe.com

    域名 uukongjian.com 更换为 itwxe.com,笔名 SunnyBear 更改为 IT王小二. 一.前言 4 月 21 号域名备案通过,开始折腾新买的服务器,本来这篇文章在 5 月 1 ...

  6. Linux - last 命令

    前言 为啥写这篇?因为听 grep.sed 教程的时候有这个命令 栗子 加上工作中,运维给我排查问题的时候也用到了,感觉挺重要,先了解为敬! 命令作用 显示上次登录用户的列表 这个是在 Linux 下 ...

  7. paramiko 详解

    Paramiko是用python语言写的一个模块,远程连接到Linux服务器,查看上面的日志状态,批量配置远程服务器,文件上传,文件下载等 初始化一些参数: host = "120.24.2 ...

  8. GO学习-(14) Go语言基础之接口

    Go语言基础之接口 接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节. 接口 接口类型 在Go语言中接口(interface)是一种类型,一种抽象的类 ...

  9. Docker删除某个容器时失败解决方案

    删除某个容器时,报错 ocker rm 容器id   image is being used by stopped container e11efb30362a   该报错的原因是要删除的该镜像,被某 ...

  10. 元素定位工具ChroPath - Chrome浏览器插件

    一 ChroPath的作用 可以自动识别元素定位表达式,对于系统需要定位元素多时,可使用这种方法减轻定位工作量,但需要验证 二 ChroPath的安装 下载ChroPath -> 在谷歌浏览器访 ...