一、背景

之前写过的几个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. 云计算OpenStack核心组件---neutron网络服务(8)*****

    一.neutron介绍 1.Neutron概述 传统的网络管理方式很大程度上依赖于管理员手工配置和维护各种网络硬件设备:而云环境下的网络已经变得非常复杂,特别是在多租户场景里,用户随时都可能需要创建. ...

  2. python基础之字典、集合

    一.字典(dictionary) 作用:存多个值,key-value存取,取值速度快 定义:key必须是不可变类型,value可以是任意类型 字典是一个无序的,可以修改的,元素呈键值对的形式,以逗号分 ...

  3. python3 ftplib模块连接FTP

    from ftplib import FTP_TLS import os import re class MyFtp(FTP_TLS): """继承FTP类"& ...

  4. 惊奇发现KEIL也可以C++编译了

    在Github上面浏览下载的一个工程,可以用KEIL打开,但是我竟然找不到mian函数.找了一圈发现是用到了面向对象的编程方法,那就必须支持C++,他怎么实现的呢? 看配置工程:明显的一个不一样 -- ...

  5. <fmt:formatDate> 标签,日期格式化问题(Day_24)

    一个时间显示问题,出生日期显示应为: yyyy-MM-dd,却显示: GMT格式(Wed Jun 15 00:00:00 CST 1983) 解决方案: 将图一改为图二. 图一: 图二: 最后: 注意 ...

  6. 原生基础js脚本实现--在线答题系统

    全部代码在最下面----需要的直接往下翻 html方面的代码  : 正确的答案 value=s <!DOCTYPE html> <html lang="en"&g ...

  7. Django中的中英文切换

    setting.py文件中 其中 zh-Hans是简体中文 zh-Hant是繁体中文 所以更改setttings.py 下 LANGUAGE_CODE = 'zh-Hans'即可 # 英文 LANGU ...

  8. 使用vue-i18n实现中英文切换(内含动态属性的绑定)

    最近做学生管理系统,因为有国外的学生,所以要进行中英文切换,查了查Vue中使用vue-i18n插件能够实现网页的中英文切换,学习内容如下: 一.下载vue-i18n插件 npm install vue ...

  9. MyBatis-框架使用和分析

      一.基础知识 MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射.MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作.MyBatis 可 ...

  10. 3D车道线检测:Gen-LaneNet

    3D车道线检测:Gen-LaneNet Gen-LaneNet: A Generalized and Scalable Approach for 3D Lane Detection 论文链接:http ...