一、背景

之前写过的几个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. COS 数据湖最佳实践:基于 Serverless 架构的入湖方案

    01 前言 数据湖(Data Lake)概念自2011年被推出后,其概念定位.架构设计和相关技术都得到了飞速发展和众多实践,数据湖也从单一数据存储池概念演进为包括 ETL 分析.数据转换及数据处理的下 ...

  2. Azure DevOps(一)利用Azure DevOps Pipeline 构建应用程序镜像到AWS ECR

    一,引言 最近项目上让开始学习AWS,作为一名合格的开发人员,当然也是学会利用Azure DevOps Pipeline 将应用程序部署到 AWS ECS(完全托管的容器编排服务).我们要学会将应用程 ...

  3. CentOS7启动SSH服务报:Job for ssh.service failed because the control process exited with error code

    CentOS7启动SSH服务报:Job for ssh.service failed because the control process exited with error code....... ...

  4. 【转载】一次「Too many open files」故障

    一次「Too many open files」故障 发表于2015-08-02 昨天,项目的 ElasticSearch 服务挂了,我说的挂可不是进程没了,因为有 Supervisor 保护,而是服务 ...

  5. Jinja2模板概述

    例子一 循环语句 [root@m01 ~]# cat upstream.conf upstream web { {% for i in range(1,11) %} server 172.16.1.{ ...

  6. shell应用之cobbler批量部署

    如果使用的是原始源,可直接使用该脚本,如果是用的其它源且有cobbler安装包的可删除脚本中的配置yum源步骤.批量部署使用的软件有:cobbler dhcp httpd tftp-server xi ...

  7. sizeof()用法汇总-(转自风雷)

    sizeof()功能:计算数据空间的字节数 1.与strlen()比较       strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为'\0'的数组元素.     ...

  8. Nginx|Apache目录权限禁止执行PHP设置

    Ngnix: location ~ /upload/.*.(php|php5)?$ { deny all; } 这就是禁止upload内执行php,但是图片可以打开哦 多目录禁止: location ...

  9. Linux下安装JDK 1.8你必须知道的糟心事

    来源:Atstudy网校 1.简介 在Oracle收购Sun后,Java的一系列产品就被整合到Oracle官网中,打开官网乍眼一看也不知道去哪里下载,还的一个一个的摸索尝试,而且网上大多数都是一些Or ...

  10. 通过Dapr实现一个简单的基于.net的微服务电商系统(十五)——集中式接口文档实现

    之前有小伙伴在评论区留言说如何集成swagger,最开始没有想透给了对方一个似是而非的回答.实际上后来下来想了一下,用.NET5 提供的Source Generator其实可以很方便的实现接口集成.今 ...