diff --git a/README.md b/README.md index 19c96c8e6c47f3d04bb51be8e9b7d730da26ac11..f1519aa086bae5ffaacd5002d9c123a5ea50201c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ | 逐版本更新 | 支持 | 客户端当前版本如果与服务器相差多个版本,则根据多个版本的发布日期逐个更新。(引用组件默认生效) | | 二进制差分更新 | 支持 | 对比新老版本通过差分算法生成补丁文件。(引用组件默认生效) | | 增量更新功能 | 支持 | 相比上一个版本只更新当前修改过的文件,并且删除当前版本不存在的文件。(引用组件默认生效) | -| ~~配置文件保留更新~~ | ~~支持~~ | ~~暂时下线该功能,后期考虑开放~~ | | 强制更新 | 支持 | 打开客户端之后直接强制更新。 | | 多分支更新 | 支持 | 当一个产品有多个分支时,需要根据不同的分支更新对应的内容。 | | 最新版本推送 | 支持 | 基于Signal R实现,推送当前最新版本。 | @@ -29,7 +28,7 @@ | 黑名单 | 支持 | 在更新过程中会跳过黑名单中的文件列表和文件扩展名列表。 | | OSS | 支持 | 极简化更新,是一套独立的更新机制。只需要在文件服务器中放置version.json的版本配置文件。组件会根据配置文件中的版本信息进行更新下载。(支持Windows,MAUI Android) | | 回滚 | 待测试 | 逐版本更新时会备份每个版本,如果更新失败则逐版本回滚。 | -| 驱动更新 | 支持 | 逐版本更新时会备份每个版本的驱动文件(.inf),如果更新失败则逐版本回滚。 | +| 驱动更新 | 待测试 | 逐版本更新时会备份每个版本的驱动文件(.inf),如果更新失败则逐版本回滚。 | | 遗言 | 待测试 | 开机时和升级时会检查升级是否成功,如果失败则根据遗言还原之前的备份。遗言是更新之前就已经自动创建在C:\generalupdate_willmessages目录下的will_message.json文件。will_message.json的内容是持久化回滚备份的文件目录相关信息。(需要部署GeneralUpdate.SystemService系统服务) | | 自定义方法列表 | 支持 | 注入一个自定义方法集合,该集合会在更新启动前执行。执行自定义方法列表如果出现任何异常,将通过异常订阅通知。(推荐在更新之前检查当前软件环境) | @@ -42,7 +41,6 @@ - 快速启动: https://mp.weixin.qq.com/s/pRKPFe3eC0NSqv9ixXEiTg - 使用教程视频:https://www.bilibili.com/video/BV1FT4y1Y7hV - 文档:https://gitee.com/GeneralLibrary/GeneralUpdate/tree/master/doc -- Tag : https://github.com/GeneralLibrary/GeneralUpdate/tree/master/tag ## 3.开源地址 ## diff --git a/README_en.md b/README_en.md index ed1fc80c0da8d0adc52058aed6c2bc1828965fa9..537126a1e947f2114cb379dc51bf2e2b2fa46da5 100644 --- a/README_en.md +++ b/README_en.md @@ -15,7 +15,6 @@ | Update version-by-version | yes | If the current version of the client differs from the server by more than one version, it is updated one by one according to the release date of the multiple versions. (Reference components take effect by default) | | Binary differential update | yes | Compare the old and new versions to generate patch files by differential algorithms. (Reference components take effect by default) | | Incremental update functionality | yes | Only the currently modified files are updated compared to the previous version,And delete files that do not exist in the current version. (Reference components take effect by default) | -| ~~The configuration file remains updated~~ | no | ~~This feature is temporarily offline~~ | | Force an update | yes | Force an update directly after opening the client. | | Multi-branch updates | yes | When a product has multiple branches, you need to update the corresponding content according to different branches. | | The latest version push | yes | Based on the SignalR implementation, push the latest version. | @@ -40,7 +39,6 @@ - Quick Start: https://mp.weixin.qq.com/s/pRKPFe3eC0NSqv9ixXEiTg - Use the tutorial video:https://www.bilibili.com/video/BV1FT4y1Y7hV - Doc : https://gitee.com/GeneralLibrary/GeneralUpdate/tree/master/doc -- Tag : https://github.com/GeneralLibrary/GeneralUpdate/tree/master/tag ### 3.Open source address ### diff --git a/doc/md/GeneralUpdate.AspNetCore.md b/doc/md/GeneralUpdate.AspNetCore.md deleted file mode 100644 index 4166d04ea471fd2201cabdb760b374f20f7db5a4..0000000000000000000000000000000000000000 --- a/doc/md/GeneralUpdate.AspNetCore.md +++ /dev/null @@ -1,23 +0,0 @@ -## GeneralUpdate.AspNetCore - -#### 简介 - - - -#### 提供功能 - - - -#### 使用示例 - -1.安装 - -TODO:截图安装,文字解释 - -2.初始化 - -TODO:代码 - -3.启动 - -TODO:运行效果 \ No newline at end of file diff --git a/doc/md/GeneralUpdate.ClientCore.md b/doc/md/GeneralUpdate.ClientCore.md deleted file mode 100644 index a55f7feb881c1dd8134df96ecf09d57420833400..0000000000000000000000000000000000000000 --- a/doc/md/GeneralUpdate.ClientCore.md +++ /dev/null @@ -1,34 +0,0 @@ -## GeneralUpdate.ClientCore - -#### 简介 - -GeneralUpdate.ClientCore是最核心的组件之一,提供了大量主要功能。本质和Core没有区别,但是有职责上的区别ClientCore用于主程序中,更新升级助手然后关闭主程序启动升级助手。 - -#### 提供功能 - -| **功能** | **是否支持** | **备注** | -| ---------------- | ------------ | -------------------------------------------------------- | -| 断点续传 | 支持 | | -| 逐版本更新 | 支持 | | -| 二进制差分更新 | 支持 | | -| 增量更新功能 | 支持 | | -| 配置文件保留更新 | 支持 | 目前指支持深度为1的json配置文件 | -| 强制更新 | 支持 | 非强制更新可以弹出选择框供用户选择,强制更新则直接更新 | -| 多分支更新 | 支持 | 当一个产品有多个分支时,需要根据不同的分支更新对应的内容 | -| 最新版本推送 | 支持 | 基于SignalR实现 | - - - -#### 使用示例 - -1.安装 - -TODO:截图安装,文字解释 - -2.初始化 - -TODO:代码 - -3.启动 - -TODO:运行效果 \ No newline at end of file diff --git a/doc/md/GeneralUpdate.Core.md b/doc/md/GeneralUpdate.Core.md deleted file mode 100644 index 9bf1cf4fff16e006d1b1d9821d33327916633349..0000000000000000000000000000000000000000 --- a/doc/md/GeneralUpdate.Core.md +++ /dev/null @@ -1,33 +0,0 @@ -## GeneralUpdate.Core - -#### 简介 - -GeneralUpdate.Core是最核心的组件之一,提供了大量主要功能。 - -#### 提供功能 - -| **功能** | **是否支持** | **备注** | -| ---------------- | ------------ | -------------------------------------------------------- | -| 断点续传 | 支持 | | -| 逐版本更新 | 支持 | | -| 二进制差分更新 | 支持 | | -| 增量更新功能 | 支持 | | -| 配置文件保留更新 | 支持 | 目前指支持深度为1的json配置文件 | -| 强制更新 | 支持 | 非强制更新可以弹出选择框供用户选择,强制更新则直接更新 | -| 多分支更新 | 支持 | 当一个产品有多个分支时,需要根据不同的分支更新对应的内容 | - - - -#### 使用示例 - -1.安装 - -TODO:截图安装,文字解释 - -2.初始化 - -TODO:代码 - -3.启动 - -TODO:运行效果 \ No newline at end of file diff --git a/doc/md/GeneralUpdate.Differential.md b/doc/md/GeneralUpdate.Differential.md deleted file mode 100644 index ee1def129cceea4e547b5dcc637e3cf2471c30ed..0000000000000000000000000000000000000000 --- a/doc/md/GeneralUpdate.Differential.md +++ /dev/null @@ -1,23 +0,0 @@ -## GeneralUpdate.Differential - -#### 简介 - - - -#### 提供功能 - - - -#### 使用示例 - -1.安装 - -TODO:截图安装,文字解释 - -2.初始化 - -TODO:代码 - -3.启动 - -TODO:运行效果 \ No newline at end of file diff --git a/doc/md/GeneralUpdate.PacketTool.md b/doc/md/GeneralUpdate.PacketTool.md deleted file mode 100644 index d2a8b153889318426094e4fed453e0d87703b760..0000000000000000000000000000000000000000 --- a/doc/md/GeneralUpdate.PacketTool.md +++ /dev/null @@ -1,28 +0,0 @@ -## GeneralUpdate.PacketTool - -#### 简介 - -工具使用.NET MAUI (.NET 6)进行开发,目前只支持桌面端使用。 - -#### 提供功能 - -| 功能 | 支持 | 备注 | -| ------------------ | ------ | ------------------------------------------------------------ | -| 差分更新包生成 | 是 | 根据上一个版本和当前版本进行对比找出需要更新的文件或新添加文件。 | -| 自动上传更新包 | 开发中 | 将生成好的差分更新包自动上传至服务器。 | -| 可编辑选择差分文件 | 开发中 | 可视化查看差分包的打包内容,并可选择打包文件。 | -| 多平台支持 | 部分 | 仅支持Windows、Linux、MacCatalyst。 | - -#### 使用示例 - - - -Source path:表示上一个版本的文件夹路径。 - -Target path:表示当前版本文件夹路径。 - -Patch path:表示最终生成差分包的路径。 - -Is Publish:如果勾选则将生成好的差分包通过HTTP上传,并自动在数据库插入本次发布的版本信息。 - -Build:通过递归比对Source path和Target path文件夹下所有的工程文件(DLL,exe...等),通过二进制差分检查、增量检查分析出需要更新的文件列表按照文件夹结构,打包更新包。 \ No newline at end of file diff --git a/doc/md/GeneralUpdate.Single.md b/doc/md/GeneralUpdate.Single.md deleted file mode 100644 index 8a2cf8fe0e1c8fe751695d72009c6885c0563490..0000000000000000000000000000000000000000 --- a/doc/md/GeneralUpdate.Single.md +++ /dev/null @@ -1,23 +0,0 @@ -## GeneralUpdate.Single - -#### 简介 - - - -#### 提供功能 - - - -#### 使用示例 - -1.安装 - -TODO:截图安装,文字解释 - -2.初始化 - -TODO:代码 - -3.启动 - -TODO:运行效果 \ No newline at end of file diff --git a/doc/md/GeneralUpdate.Zip.md b/doc/md/GeneralUpdate.Zip.md deleted file mode 100644 index 8388d6dd4e484510eb1957e3f7cb519016633223..0000000000000000000000000000000000000000 --- a/doc/md/GeneralUpdate.Zip.md +++ /dev/null @@ -1,23 +0,0 @@ -## GeneralUpdate.ZIP - -#### 简介 - - - -#### 提供功能 - - - -#### 使用示例 - -1.安装 - -TODO:截图安装,文字解释 - -2.初始化 - -TODO:代码 - -3.启动 - -TODO:运行效果 \ No newline at end of file diff --git "a/doc/md/\347\273\204\344\273\266\347\256\200\344\273\213.md" "b/doc/md/\347\273\204\344\273\266\347\256\200\344\273\213.md" deleted file mode 100644 index 6fbf57566f9b282799ca4f87971799bd7aabfa57..0000000000000000000000000000000000000000 --- "a/doc/md/\347\273\204\344\273\266\347\256\200\344\273\213.md" +++ /dev/null @@ -1,122 +0,0 @@ -### 1.GeneralUpdate是什么? - -GeneralUpdate将被规划为全平台全栈软件,不受限任何语言或技术的自动更新组件。 - -##### 开源地址 - -- https://github.com/JusterZhu/GeneralUpdate -- https://gitee.com/Juster-zhu/GeneralUpdate - -##### 帮助文档 ##### - -- 讲解视频: https://www.bilibili.com/video/BV1aX4y137dd -- 官方网站: http://justerzhu.cn/ -- 快速启动: https://mp.weixin.qq.com/s/pRKPFe3eC0NSqv9ixXEiTg -- 使用教程视频:https://www.bilibili.com/video/BV1FT4y1Y7hV - -##### 沟通交流 - -- 免费问题解答: https://github.com/JusterZhu/GeneralUpdate/issues -- 免费技术交流: -- 开源项目使用讨论: - - - -##### 商务合作 - -定制化二次开发,技术咨询。 - -- 邮箱:zhuzhen723723@outlook.com - - - -## 2.统一语言(Unifying Language) - -在开始使用GeneralUpdate之前我们需要先知道体系中的一些基础概念。 - -- Client:是指你的主应用程序,是被更新的客户端。也可理解为是公司的产品。 - -- Upgrade:是指升级程序,它将是一个独立的进程。需要和Client放在同一级目录下,在使用(或编码)的过程中不可以和任何业务或设计关联、必须保持独立引用。 -- Server:是指服务端应用(ASP.NET)将提供版本更新信息交互、版本验证功能。 - - - -### 3.GeneralUpdate提供什么? - -##### 组件功能 - -| **功能** | **是否支持** | **备注** | -| ------------------------------ | ------------ | ------------------------------------------------------------ | -| 断点续传 | 支持 | | -| 逐版本更新 | 支持 | | -| 二进制差分更新 | 支持 | | -| 增量更新功能 | 支持 | | -| 配置文件保留更新 | 支持 | 目前指支持深度为1的json配置文件 | -| 强制更新 | 支持 | 非强制更新可以弹出选择框供用户选择,强制更新则直接更新 | -| 多分支更新 | 支持 | 当一个产品有多个分支时,需要根据不同的分支更新对应的内容 | -| 版本校验、更新信息 | 支持 | 可验证版本是否需要更新 | -| 最新版本推送 | 支持 | 基于SignalR实现 | -| 客户端程序、服务端程序应用更新 | 支持 | C/S和B/S程序均可使用 | -| 多平台、操作系统 | 部分支持 | Linux、MacCatalyst、Windows | -| 多语言 | 待验证 | 也可将本组件编写为控制台程序,作为更新“脚本”。供其他语言的应用程序调用更新。 | - - - -##### 打包工具 - -GeneralUpdate.PacketTool使用.NET MAUI(.NET 6)编写的桌面端打包程序。 - -| 功能 | 支持 | 备注 | -| ------------------ | ------ | ------------------------------------------------------------ | -| 差分更新包生成 | 是 | 根据上一个版本和当前版本进行对比找出需要更新的文件或新添加文件。 | -| 自动上传更新包 | 开发中 | 将生成好的差分更新包自动上传至服务器。 | -| 可编辑选择差分文件 | 开发中 | 可视化查看差分包的打包内容,并可选择打包文件。 | -| 多平台支持 | 部分 | 仅支持Windows、Linux、MacCatalyst。 | - - - -### 4.GeneralUpdate支持什么? - -##### .NET框架 - -| 框架名称 | 是否支持 | -| -------------------- | -------- | -| .NET Core 2.0 | 支持 | -| .NET 5 6 7 8 | 支持 | -| .NET Framework 4.6.1 | 支持 | - - - -##### UI框架 - -| UI框架名称 | 是否支持 | -| ----------------- | ------------------- | -| WPF | 支持 | -| UWP | 商店模式下不可更新 | -| MAUI | 正在兼容(windows) | -| Avalonia | 支持 | -| WinUI | 待验证,等待反馈 | -| Console(控制台) | 支持 | -| Winform | 支持 | - - - -##### 服务端框架 - -| 服务端框架 | 是否支持 | -| ---------- | -------- | -| ASP.NET | 待验证 | - - - -##### 操作系统 - -| 操作系统名称 | 是否支持 | -| -------------------------------- | -------- | -| Windows | 支持 | -| Linux | 支持 | -| MacCatalyst | 支持 | -| iOS | 暂不支持 | -| Android | 暂不支持 | -| 树莓派(IoT) | 待验证 | -| 国产操作系统(华为海思、麒麟等) | 待验证 | \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Client/MySample.cs b/src/c#/GeneralUpdate.Client/MySample.cs index 72e631dacad5fabeb9494c7ffee3973810664778..999b10f7ae2bbf8eeebf47058bf16934f5ebfa68 100644 --- a/src/c#/GeneralUpdate.Client/MySample.cs +++ b/src/c#/GeneralUpdate.Client/MySample.cs @@ -1,6 +1,5 @@ using GeneralUpdate.ClientCore; using GeneralUpdate.Core.Bootstrap; -using GeneralUpdate.Core.ContentProvider; using GeneralUpdate.Core.Domain.Entity; using GeneralUpdate.Core.Domain.Enum; using GeneralUpdate.Core.Driver; diff --git a/src/c#/GeneralUpdate.ClientCore/Differential/Config/.gitkeep b/src/c#/GeneralUpdate.ClientCore/Differential/Config/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/c#/GeneralUpdate.ClientCore/Differential/Config/Cache/.gitkeep b/src/c#/GeneralUpdate.ClientCore/Differential/Config/Cache/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/c#/GeneralUpdate.ClientCore/Differential/Config/Handles/.gitkeep b/src/c#/GeneralUpdate.ClientCore/Differential/Config/Handles/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/c#/GeneralUpdate.ClientCore/GeneralUpdate.ClientCore.csproj b/src/c#/GeneralUpdate.ClientCore/GeneralUpdate.ClientCore.csproj index de6d08b8b4db4e9e2a7dad137a7a1f35c373b269..fffb448fad35788449d7459c0414f92e2d3a5274 100644 --- a/src/c#/GeneralUpdate.ClientCore/GeneralUpdate.ClientCore.csproj +++ b/src/c#/GeneralUpdate.ClientCore/GeneralUpdate.ClientCore.csproj @@ -32,9 +32,6 @@ - - - @@ -62,12 +59,9 @@ - - - @@ -142,7 +136,6 @@ - @@ -157,26 +150,17 @@ - - - - - - - - - - - + + @@ -184,9 +168,7 @@ - - @@ -239,7 +221,6 @@ - @@ -257,31 +238,20 @@ - - - - - - - - - - - - + diff --git a/src/c#/GeneralUpdate.ClientCore/Hubs/VersionHub.cs b/src/c#/GeneralUpdate.ClientCore/Hubs/VersionHub.cs index d8540127169c22e85247fe6dc1e26263252b431d..6b656f141c74613feb7a41bec04c9f562ec5516c 100644 --- a/src/c#/GeneralUpdate.ClientCore/Hubs/VersionHub.cs +++ b/src/c#/GeneralUpdate.ClientCore/Hubs/VersionHub.cs @@ -1,4 +1,4 @@ -using GeneralUpdate.Core.Utils; +using GeneralUpdate.Core.ContentProvider; using Microsoft.AspNetCore.SignalR.Client; using System; using System.Threading.Tasks; @@ -122,7 +122,7 @@ namespace GeneralUpdate.ClientCore.Hubs if (_receiveMessageCallback == null || string.IsNullOrWhiteSpace(message)) return; try { - var clientParameter = SerializeUtil.Deserialize(message); + var clientParameter = FileProvider.Deserialize(message); if (clientParameter == null) throw new ArgumentNullException($"'VersionHub' Receiving server push version information deserialization failed , receive content : {message} ."); _receiveMessageCallback.Invoke(clientParameter); } diff --git a/src/c#/GeneralUpdate.ClientCore/Utils/.gitkeep b/src/c#/GeneralUpdate.ClientCore/Utils/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/c#/GeneralUpdate.ClientCore/ZipFactory/G7z/.gitkeep b/src/c#/GeneralUpdate.ClientCore/ZipFactory/G7z/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/c#/GeneralUpdate.ClientCore/ZipFactory/GZip/.gitkeep b/src/c#/GeneralUpdate.ClientCore/ZipFactory/GZip/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/c#/GeneralUpdate.Core/Bootstrap/AbstractBootstrap.cs b/src/c#/GeneralUpdate.Core/Bootstrap/AbstractBootstrap.cs index 081f6ecf9f2beced84a4bd46f79bc2c1144b0a5b..637f467720280fb8347fe63677a790206969c0a9 100644 --- a/src/c#/GeneralUpdate.Core/Bootstrap/AbstractBootstrap.cs +++ b/src/c#/GeneralUpdate.Core/Bootstrap/AbstractBootstrap.cs @@ -145,7 +145,7 @@ namespace GeneralUpdate.Core.Bootstrap Contract.Requires(option != null); if (value == null) { - this._options.TryRemove(option, out UpdateOptionValue removed); + this._options.TryRemove(option, out _); } else { diff --git a/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Comparer.cs b/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Comparer.cs index ae8cfcda4da6e2e1c63b1a05f46bbf9aacf02b0e..be5f91e732a11ab962567bbb48489242febcdaf8 100644 --- a/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Comparer.cs +++ b/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Comparer.cs @@ -64,4 +64,4 @@ namespace GeneralUpdate.Core.ContentProvider } } } -} +} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Filter.cs b/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Filter.cs index ba44771876aecef5a11fa057599bd37277a0bcea..e399f57468c493edf8e1b859af7b1a0681a26aaa 100644 --- a/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Filter.cs +++ b/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Filter.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; namespace GeneralUpdate.Core.ContentProvider { @@ -31,4 +29,4 @@ namespace GeneralUpdate.Core.ContentProvider /// public static List GetBlackFileFormats() => _blackFileFormats ?? new List() { ".patch", ".7z", ".zip", ".rar", ".tar", ".json" }; } -} +} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Manage.cs b/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Manage.cs index 77fa0b8604e31d3ad9b1f61e2266c4fb139562c2..97580db8837532ce2d9267c5c7abb2945f6ad78e 100644 --- a/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Manage.cs +++ b/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Manage.cs @@ -1,6 +1,4 @@ -using GeneralUpdate.Core.Exceptions; -using GeneralUpdate.Core.HashAlgorithms; -using System; +using System; using System.Collections.Generic; using System.IO; diff --git a/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Serialization.cs b/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Serialization.cs index 4a03e465486c88a1c1109194e433d0b68a1d5bb0..ebf0a6de1c501082f7f684d76b95156b76d5efbb 100644 --- a/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Serialization.cs +++ b/src/c#/GeneralUpdate.Core/ContentProvider/FileProvider-Serialization.cs @@ -1,5 +1,7 @@ using Newtonsoft.Json; +using System; using System.IO; +using System.Text; namespace GeneralUpdate.Core.ContentProvider { @@ -25,5 +27,35 @@ namespace GeneralUpdate.Core.ContentProvider } return default(T); } + + /// + /// Convert object to base64 string. + /// + /// + /// + public static string Serialize(object obj) + { + if (obj == null) return string.Empty; + var json = JsonConvert.SerializeObject(obj); + var bytes = Encoding.Default.GetBytes(json); + var base64str = Convert.ToBase64String(bytes); + return base64str; + } + + /// + /// Convert base64 object to string. + /// + /// + /// + /// + public static T Deserialize(string str) + { + var obj = default(T); + if (string.IsNullOrEmpty(str)) return obj; + byte[] bytes = Convert.FromBase64String(str); + var json = Encoding.Default.GetString(bytes); + var result = JsonConvert.DeserializeObject(json); + return result; + } } } \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Core/Domain/Entity/Assembler/ProcessAssembler.cs b/src/c#/GeneralUpdate.Core/Domain/Entity/Assembler/ProcessAssembler.cs index 39a1c69ab1fc46cb846cb1d2a549ae10ce522215..88eb236c251998df96eef8cccaf96b71b1aa37a7 100644 --- a/src/c#/GeneralUpdate.Core/Domain/Entity/Assembler/ProcessAssembler.cs +++ b/src/c#/GeneralUpdate.Core/Domain/Entity/Assembler/ProcessAssembler.cs @@ -1,4 +1,4 @@ -using GeneralUpdate.Core.Utils; +using GeneralUpdate.Core.ContentProvider; using System; using System.Text; @@ -9,13 +9,13 @@ namespace GeneralUpdate.Core.Domain.Entity.Assembler public static string ToBase64(ProcessInfo info) { if (info == null) throw new ArgumentNullException(nameof(info)); - return SerializeUtil.Serialize(info); + return FileProvider.Serialize(info); } public static string ToBase64(ParamsOSS info) { if (info == null) throw new ArgumentNullException(nameof(info)); - return SerializeUtil.Serialize(info); + return FileProvider.Serialize(info); } public static Packet ToPacket(ProcessInfo info) diff --git a/src/c#/GeneralUpdate.Core/GeneralUpdateBootstrap.cs b/src/c#/GeneralUpdate.Core/GeneralUpdateBootstrap.cs index 8b4965b51c0d9c9c9239bf476dffc1a42ac27c60..67913d5413881fb2c541e190524b5cb8cbae7c70 100644 --- a/src/c#/GeneralUpdate.Core/GeneralUpdateBootstrap.cs +++ b/src/c#/GeneralUpdate.Core/GeneralUpdateBootstrap.cs @@ -4,7 +4,6 @@ using GeneralUpdate.Core.Domain.Entity; using GeneralUpdate.Core.Domain.Entity.Assembler; using GeneralUpdate.Core.Domain.Enum; using GeneralUpdate.Core.Strategys; -using GeneralUpdate.Core.Utils; using System; using System.IO; using System.Threading.Tasks; @@ -23,7 +22,7 @@ namespace GeneralUpdate.Core try { var base64 = Environment.GetEnvironmentVariable("ProcessBase64", EnvironmentVariableTarget.User); - var processInfo = SerializeUtil.Deserialize(base64); + var processInfo = FileProvider.Deserialize(base64); Packet = ProcessAssembler.ToPacket(processInfo); Packet.AppType = AppType.UpgradeApp; Packet.TempPath = $"{FileProvider.GetTempDirectory(processInfo.LastVersion)}{Path.DirectorySeparatorChar}"; diff --git a/src/c#/GeneralUpdate.Core/Pipelines/Middleware/ConfigMiddleware.cs b/src/c#/GeneralUpdate.Core/Pipelines/Middleware/ConfigMiddleware.cs deleted file mode 100644 index 8d5046639a71463872976ab7548ef9ee150d3614..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Core/Pipelines/Middleware/ConfigMiddleware.cs +++ /dev/null @@ -1,22 +0,0 @@ -using GeneralUpdate.Core.Domain.Enum; -using GeneralUpdate.Core.Events; -using GeneralUpdate.Core.Events.MultiEventArgs; -using GeneralUpdate.Core.Pipelines.Context; -using GeneralUpdate.Differential.Config; -using System; -using System.Threading.Tasks; - -namespace GeneralUpdate.Core.Pipelines.Middleware -{ - [Obsolete("This feature is temporarily deprecated in the current version pending refactoring.")] - public class ConfigMiddleware : IMiddleware - { - public async Task InvokeAsync(BaseContext context, MiddlewareStack stack) - { - EventManager.Instance.Dispatch>(this, new MultiDownloadProgressChangedEventArgs(context.Version, ProgressType.Hash, "Update configuration file ...")); - await ConfigFactory.Instance.Deploy(); - var node = stack.Pop(); - if (node != null) await node.Next.Invoke(context, stack); - } - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Core/Utils/SerializeUtil.cs b/src/c#/GeneralUpdate.Core/Utils/SerializeUtil.cs deleted file mode 100644 index 14d5a27ad2ab5b801b46a2499cd954308ffd7021..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Core/Utils/SerializeUtil.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Text; - -namespace GeneralUpdate.Core.Utils -{ - /// - /// Arbitrary object serialization. - /// - public class SerializeUtil - { - /// - /// Convert object to base64 string. - /// - /// - /// - public static string Serialize(object obj) - { - if (obj == null) return string.Empty; - var json = JsonConvert.SerializeObject(obj); - var bytes = Encoding.Default.GetBytes(json); - var base64str = Convert.ToBase64String(bytes); - return base64str; - } - - /// - /// Convert base64 object to string. - /// - /// - /// - /// - public static T Deserialize(string str) - { - var obj = default(T); - if (string.IsNullOrEmpty(str)) return obj; - byte[] bytes = Convert.FromBase64String(str); - var json = Encoding.Default.GetString(bytes); - var result = JsonConvert.DeserializeObject(json); - return result; - } - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/Config/Cache/ConfigCache.cs b/src/c#/GeneralUpdate.Differential/Config/Cache/ConfigCache.cs deleted file mode 100644 index bcd62a64db0ff70f3cd57136f7b6038d1cd6ce8e..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Differential/Config/Cache/ConfigCache.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Collections.Immutable; - -namespace GeneralUpdate.Differential.Config.Cache -{ - public class ConfigCache : ICache where TEntity : class - { - #region Private Members - - private ImmutableDictionary _cache = null; - private ImmutableDictionary.Builder _cacheBuilder = null; - - #endregion Private Members - - #region Constructors - - public ConfigCache() - { - _cacheBuilder = ImmutableDictionary.Create().ToBuilder(); - } - - #endregion Constructors - - #region Public Properties - - public ImmutableDictionary Cache { get => _cache; private set => _cache = value; } - - #endregion Public Properties - - #region Public Methods - - public void TryAdd(string key, TEntity entity) - { - if (!_cacheBuilder.ContainsKey(key)) _cacheBuilder.Add(key, entity); - } - - public TEntity TryGet(string key) - { - TEntity result = null; - if (_cacheBuilder.ContainsKey(key)) _cacheBuilder.TryGetValue(key, out result); - return result; - } - - public bool TryRemove(string key) - { - bool isRemove = false; - if (_cacheBuilder.ContainsKey(key)) isRemove = _cacheBuilder.Remove(key); - return isRemove; - } - - public void Build() - { - if (Cache == null) Cache = _cacheBuilder.ToImmutableDictionary(); - } - - public void Dispose() - { - if (Cache != null) - { - Cache.Clear(); - Cache = null; - } - - if (_cacheBuilder != null) - { - _cacheBuilder.Clear(); - _cacheBuilder = null; - } - } - - #endregion Public Methods - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/Config/Cache/ConfigEntity.cs b/src/c#/GeneralUpdate.Differential/Config/Cache/ConfigEntity.cs deleted file mode 100644 index c81f6d712c74a1d700c68810a1d210e267c6b261..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Differential/Config/Cache/ConfigEntity.cs +++ /dev/null @@ -1,34 +0,0 @@ -using GeneralUpdate.Differential.Config.Handles; - -namespace GeneralUpdate.Differential.Config.Cache -{ - public class ConfigEntity - { - /// - /// file name - /// - public string Name { get; set; } - - /// - /// file hash code . - /// - public string Hash { get; set; } - - /// - /// configuation file content. - /// - public object Content { get; set; } - - /// - /// configuration file path. - /// - public string Path { get; set; } - - public string OldPath { get; set; } - - /// - /// handle type (.json .ini .xml .db) . - /// - public HandleEnum Handle { get; set; } - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/Config/Cache/ICache.cs b/src/c#/GeneralUpdate.Differential/Config/Cache/ICache.cs deleted file mode 100644 index a0e11d471129c6bba7df2cb9ff2768a8bb042d1b..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Differential/Config/Cache/ICache.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace GeneralUpdate.Differential.Config.Cache -{ - /// - /// Cache operation class. - /// - /// - public interface ICache where TEntity : class - { - /// - /// add cache. - /// - /// file hash - /// configuration file content. - void TryAdd(string key, TEntity entity); - - /// - /// remove cache. - /// - /// file hash - /// - bool TryRemove(string key); - - /// - /// get cache configuration file content. - /// - /// file hash - /// configuration file content. - TEntity TryGet(string key); - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/Config/ConfigFactory.cs b/src/c#/GeneralUpdate.Differential/Config/ConfigFactory.cs deleted file mode 100644 index 5033c1cb8a0688b4acb8a27d4f1fb2d39e53c71f..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Differential/Config/ConfigFactory.cs +++ /dev/null @@ -1,276 +0,0 @@ -using GeneralUpdate.Core.ContentProvider; -using GeneralUpdate.Core.HashAlgorithms; -using GeneralUpdate.Differential.Config.Cache; -using GeneralUpdate.Differential.Config.Handles; -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; - -namespace GeneralUpdate.Differential.Config -{ - /// - /// Update local configuration file.[Currently only files with a depth of 1 are supported.] - /// Currently only json files are supported. - /// - public sealed class ConfigFactory : IDisposable - { - #region Private Members - - private ConfigCache _configCache; - private string _appPath, _scanPath; - private List _files; - private bool _disposed = false; - private static readonly object _locker = new object(); - private static ConfigFactory _instance; - - #endregion Private Members - - #region Constructors - - private ConfigFactory() - { - _configCache = new ConfigCache(); - } - - ~ConfigFactory() - { - Dispose(); - } - - #endregion Constructors - - #region Public Properties - - public static ConfigFactory Instance - { - get - { - if (_instance == null) - { - lock (_locker) - { - if (_instance == null) _instance = new ConfigFactory(); - } - } - return _instance; - } - } - - #endregion Public Properties - - #region Public Methods - - /// - /// Deploy configuration file. - /// - public async Task Deploy() - { - try - { - if (_configCache.Cache != null) - { - foreach (var cacheItem in _configCache.Cache) - { - var value = cacheItem.Value; - if (value == null) continue; - var hashAlgorithm = new Sha256HashAlgorithm(); - var hash = hashAlgorithm.ComputeHash(value.OldPath); - var oldEntity = await Handle(value.OldPath, hash); - await InitHandle(value.Handle).Write(oldEntity, value); - } - Dispose(); - } - } - catch (Exception ex) - { - throw new Exception($"Deploy config error : {ex.Message} .", ex.InnerException); - } - } - - /// - /// Scan configuration files and cache, backup. - /// - /// The application directory that needs to be updated. - /// update package directory. - /// - /// - public async Task Scan(string appPath = null, string scanPath = null) - { - try - { - _disposed = false; - _appPath = appPath ?? Environment.CurrentDirectory; - _scanPath = scanPath ?? Environment.CurrentDirectory; - if (!Directory.Exists(_appPath) || !Directory.Exists(_scanPath)) return; - List files = new List(); - Find(_scanPath, ref files); - if (files.Count == 0) return; - await Cache(_files = files); - } - catch (Exception ex) - { - throw new Exception($"Scan config files error : {ex.Message} .", ex.InnerException); - } - } - - /// - /// release all resources. - /// - /// dispose exception - public void Dispose() - { - if (_disposed) return; - - try - { - if (_configCache != null) - { - _configCache.Dispose(); - _configCache = null; - } - if (_files != null) - { - _files.Clear(); - _files = null; - } - _disposed = true; - } - catch (Exception ex) - { - _disposed = false; - throw new Exception($"'Dispose' error :{ex.Message} .", ex.InnerException); - } - } - - #endregion Public Methods - - #region Private Methods - - /// - /// Find matching files recursively. - /// - /// root directory - /// result file list - private void Find(string rootDirectory, ref List files) - { - var rootDirectoryInfo = new DirectoryInfo(rootDirectory); - foreach (var file in rootDirectoryInfo.GetFiles()) - { - var extensionName = Path.GetExtension(file.Name); - if (!FileProvider.GetBlackFileFormats().Contains(extensionName)) continue; - var fullName = file.FullName; - files.Add(fullName); - } - foreach (var dir in rootDirectoryInfo.GetDirectories()) - { - Find(dir.FullName, ref files); - } - } - - /// - /// All resources are cached and backed up. - /// - /// - /// - private async Task Cache(IEnumerable files) - { - if (_files == null) return; - try - { - foreach (var file in files) - { - var hashAlgorithm = new Sha256HashAlgorithm(); - var hash = hashAlgorithm.ComputeHash(file); - var entity = await Handle(file, hash); - _configCache.TryAdd(hash, entity); - } - _configCache.Build(); - } - catch (Exception ex) - { - throw new Exception($"'Cache' error :{ex.Message} .", ex.InnerException); - } - } - - /// - /// Process file content. - /// - /// file path - /// hash - /// - private async Task Handle(string file, string hash) - { - var entity = new ConfigEntity(); - entity.Path = file; - entity.Name = Path.GetFileName(file); - entity.OldPath = Path.Combine(_appPath, entity.Name); - entity.Hash = hash; - entity.Handle = ToEnum(file); - entity.Content = await InitHandle(entity.Handle).Read(file); - return entity; - } - - /// - /// Initialize the corresponding file processing object. - /// - /// file entity - /// handle enum - /// handle - private IHandle InitHandle(HandleEnum handleEnum) where TEntity : class - { - IHandle handle = null; - switch (handleEnum) - { - case HandleEnum.DB: - handle = new DBHandle(); - break; - - case HandleEnum.INI: - handle = new IniHandle(); - break; - - case HandleEnum.JSON: - handle = new JsonHandle(); - break; - - case HandleEnum.XML: - handle = new XmlHandle(); - break; - } - return handle; - } - - /// - /// Convert enumeration value according to file type. - /// - /// file path - /// handle enum - private HandleEnum ToEnum(string file) - { - var fileExtension = Path.GetExtension(file); - var handleEnum = HandleEnum.NONE; - switch (fileExtension) - { - case ".db": - handleEnum = HandleEnum.DB; - break; - - case ".ini": - handleEnum = HandleEnum.INI; - break; - - case ".json": - handleEnum = HandleEnum.JSON; - break; - - case ".xml": - handleEnum = HandleEnum.XML; - break; - } - return handleEnum; - } - - #endregion Private Methods - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/Config/Handles/DBHandle.cs b/src/c#/GeneralUpdate.Differential/Config/Handles/DBHandle.cs deleted file mode 100644 index 9cbc13de1c6519cd2260e1e4b8fc937bb9b11972..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Differential/Config/Handles/DBHandle.cs +++ /dev/null @@ -1,31 +0,0 @@ -using GeneralUpdate.Core.CustomAwaiter; -using System; -using System.Threading.Tasks; - -namespace GeneralUpdate.Differential.Config.Handles -{ - public class DBHandle : IHandle, IAwaiter where TEntity : class - { - public bool IsCompleted => throw new NotImplementedException(); - - public TEntity GetResult() - { - throw new NotImplementedException(); - } - - public void OnCompleted(Action continuation) - { - throw new NotImplementedException(); - } - - public Task Read(string path) - { - throw new NotImplementedException(); - } - - public Task Write(TEntity oldEntity, TEntity newEntity) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/Config/Handles/HandleEnum.cs b/src/c#/GeneralUpdate.Differential/Config/Handles/HandleEnum.cs deleted file mode 100644 index ee5c90617e95a57af7b4cdeae9866a640cb9a85d..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Differential/Config/Handles/HandleEnum.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace GeneralUpdate.Differential.Config.Handles -{ - public enum HandleEnum - { - NONE = 0, - INI, - JSON, - XML, - DB - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/Config/Handles/IHandle.cs b/src/c#/GeneralUpdate.Differential/Config/Handles/IHandle.cs deleted file mode 100644 index 6d0839b1338f40b1c4e477036278b0f438b8cc9a..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Differential/Config/Handles/IHandle.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; - -namespace GeneralUpdate.Differential.Config.Handles -{ - public interface IHandle where TEntity : class - { - /// - /// Write the cache content to the file to be updated. - /// - /// - /// - /// - Task Write(TEntity oldEntity, TEntity newEntity); - - /// - /// read file content. - /// - /// file path - /// - Task Read(string path); - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/Config/Handles/IniHandle.cs b/src/c#/GeneralUpdate.Differential/Config/Handles/IniHandle.cs deleted file mode 100644 index 2ea2cb0c483044b503fcb15773b7b211f545d010..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Differential/Config/Handles/IniHandle.cs +++ /dev/null @@ -1,130 +0,0 @@ -using GeneralUpdate.Core.CustomAwaiter; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace GeneralUpdate.Differential.Config.Handles -{ - public class IniHandle : IHandle, IAwaiter where TEntity : class - { - public bool IsCompleted => throw new NotImplementedException(); - - public TEntity GetResult() - { - throw new NotImplementedException(); - } - - public void OnCompleted(Action continuation) - { - throw new NotImplementedException(); - } - - public Task Read(string path) - { - throw new NotImplementedException(); - } - - public Task Write(TEntity oldEntity, TEntity newEntity) - { - throw new NotImplementedException(); - } - - private Dictionary> ParseIniFile(string filePath) - { - Dictionary> iniData = new Dictionary>(); - string currentSection = ""; - - foreach (string line in File.ReadLines(filePath)) - { - string trimmedLine = line.Trim(); - - if (trimmedLine.StartsWith("[") && trimmedLine.EndsWith("]")) - { - currentSection = trimmedLine.Substring(1, trimmedLine.Length - 2); - iniData[currentSection] = new Dictionary(); - } - else if (!string.IsNullOrEmpty(trimmedLine) && trimmedLine.Contains("=")) - { - string[] parts = trimmedLine.Split('='); - string key = parts[0].Trim(); - string value = parts[1].Trim(); - iniData[currentSection][key] = value; - } - } - - return iniData; - } - - private static Dictionary> GetIniFileDiff( - Dictionary> originalIni, - Dictionary> targetIni) - { - Dictionary> diffIni = new Dictionary>(); - - foreach (var sectionKey in originalIni.Keys) - { - if (!targetIni.ContainsKey(sectionKey)) - { - diffIni[sectionKey] = originalIni[sectionKey]; - } - else - { - Dictionary originalSection = originalIni[sectionKey]; - Dictionary targetSection = targetIni[sectionKey]; - Dictionary diffSection = originalSection - .Where(kv => !targetSection.ContainsKey(kv.Key) || targetSection[kv.Key] != kv.Value) - .ToDictionary(kv => kv.Key, kv => kv.Value); - - if (diffSection.Count > 0) - { - diffIni[sectionKey] = diffSection; - } - } - } - - return diffIni; - } - - private void MergeIniFiles( - Dictionary> targetIni, - Dictionary> diffIni) - { - foreach (var sectionKey in diffIni.Keys) - { - if (!targetIni.ContainsKey(sectionKey)) - { - targetIni[sectionKey] = new Dictionary(); - } - - Dictionary targetSection = targetIni[sectionKey]; - Dictionary diffSection = diffIni[sectionKey]; - - foreach (var keyValue in diffSection) - { - targetSection[keyValue.Key] = keyValue.Value; - } - } - } - - private void SaveIniFile(string filePath, Dictionary> iniData) - { - using (StreamWriter writer = new StreamWriter(filePath, false, Encoding.UTF8)) - { - foreach (var sectionKey in iniData.Keys) - { - writer.WriteLine($"[{sectionKey}]"); - - foreach (var keyValue in iniData[sectionKey]) - { - writer.WriteLine($"{keyValue.Key}={keyValue.Value}"); - } - - writer.WriteLine(); // 空行分隔不同的部分 - } - } - } - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/Config/Handles/JsonHandle.cs b/src/c#/GeneralUpdate.Differential/Config/Handles/JsonHandle.cs deleted file mode 100644 index 2c5a9cb52ecf276a572b5dbf830efc849a26a40e..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Differential/Config/Handles/JsonHandle.cs +++ /dev/null @@ -1,163 +0,0 @@ -using GeneralUpdate.Core.CustomAwaiter; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.ExceptionServices; -using System.Threading.Tasks; - -namespace GeneralUpdate.Differential.Config.Handles -{ - /// - /// JSON configuration file processing class . - /// - /// json configuration file content. - public class JsonHandle : IHandle, IAwaiter> where TContent : class - { - private bool _isCompleted; - private Exception _exception; - - public bool IsCompleted { get => _isCompleted; private set => _isCompleted = value; } - - public void OnCompleted(Action continuation) - { - if (continuation != null) continuation.Invoke(); - } - - /// - /// Read the content of the configuration file according to the path . - /// - /// file path. - /// file content. - public Task Read(string path) - { - try - { - var jsonText = File.ReadAllText(path); - return Task.FromResult(JsonConvert.DeserializeObject(jsonText)); - } - catch (Exception ex) - { - throw new Exception($"read config error : {ex.Message} !", ex.InnerException); - } - finally - { - IsCompleted = true; - } - } - - /// - /// Write the processed content to the configuration file . - /// - /// file path. - /// file content. - /// is done. - public async Task Write(TContent oldEntity, TContent newEntity) - { - try - { - var oldResult = GetPropertyValue(oldEntity, "Content"); - var newResult = GetPropertyValue(newEntity, "Content"); - var oldPath = GetPropertyValue(oldEntity, "Path"); - string json = string.Empty; - CopyValue(oldResult, newResult, ref json); - File.WriteAllText(oldPath, json); - return await Task.FromResult(true); - } - catch (Exception ex) - { - _exception = ex; - } - finally - { - IsCompleted = true; - } - return await Task.FromResult(false); - } - - /// - /// Iterate over objects and copy values . - /// - /// json object . - /// original configuration file . - /// latest configuration file . - /// result json. - private void CopyValue(T source, T target, ref string json) where T : class - { - try - { - JObject jSource = JObject.Parse(source.ToString()); - JObject jTarget = JObject.Parse(target.ToString()); - foreach (JProperty jProperty in jSource.Properties()) - { - var jFindObj = jTarget.Properties().FirstOrDefault(j => j.Name.Equals(jProperty.Name)); - if (jFindObj != null) - { - jFindObj.Value = jProperty.Value; - } - } - json = JsonConvert.SerializeObject(jTarget); - } - catch (Exception ex) - { - _exception = ex; - } - } - - private TResult GetPropertyValue(TContent entity, string propertyName) - { - TResult result = default(TResult); - Type entityType = typeof(TContent); - try - { - PropertyInfo info = entityType.GetProperty(propertyName); - result = (TResult)info.GetValue(entity); - } - catch (ArgumentNullException ex) - { - throw _exception = new ArgumentNullException("'GetPropertyValue' The method executes abnormally !", ex); - } - catch (AmbiguousMatchException ex) - { - throw _exception = new AmbiguousMatchException("'GetPropertyValue' The method executes abnormally !", ex); - } - return result; - } - - private void Read(string originalJson, string diffJson) - { - JObject originalObject = JObject.Parse(originalJson); - JObject diffObject = JObject.Parse(diffJson); - } - - private string MergeJsonObjects(JObject original, JObject diff) - { - foreach (var property in diff.Properties()) - { - // 如果差分对象中的属性值不为 null,则更新原始对象的属性值 - if (property.Value.Type != JTokenType.Null) - { - original[property.Name] = property.Value; - } - else - { - // 如果差分对象中的属性值为 null,则从原始对象中删除该属性 - original.Remove(property.Name); - } - } - return original.ToString(Formatting.Indented); - } - - public JsonHandle GetAwaiter() => this; - - public JsonHandle GetResult() - { - if (_exception != null) ExceptionDispatchInfo.Capture(_exception).Throw(); - return this; - } - - public async Task AsTask(JsonHandle awaiter) => await awaiter; - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/Config/Handles/XmlHandle.cs b/src/c#/GeneralUpdate.Differential/Config/Handles/XmlHandle.cs deleted file mode 100644 index e4f9267fcbab434f8b8bdd0b9b20c204cd9d0490..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Differential/Config/Handles/XmlHandle.cs +++ /dev/null @@ -1,31 +0,0 @@ -using GeneralUpdate.Core.CustomAwaiter; -using System; -using System.Threading.Tasks; - -namespace GeneralUpdate.Differential.Config.Handles -{ - public class XmlHandle : IHandle, IAwaiter where TEntity : class - { - public bool IsCompleted => throw new NotImplementedException(); - - public TEntity GetResult() - { - throw new NotImplementedException(); - } - - public void OnCompleted(Action continuation) - { - throw new NotImplementedException(); - } - - public Task Read(string path) - { - throw new NotImplementedException(); - } - - public Task Write(TEntity oldEntity, TEntity newEntity) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Differential/GeneralUpdate.Differential.csproj b/src/c#/GeneralUpdate.Differential/GeneralUpdate.Differential.csproj index cb3eba97d3d0574caf3e03a6c329d5c426984136..87164b709c2d92e915dabf8bd06498e71dd7361e 100644 --- a/src/c#/GeneralUpdate.Differential/GeneralUpdate.Differential.csproj +++ b/src/c#/GeneralUpdate.Differential/GeneralUpdate.Differential.csproj @@ -13,6 +13,12 @@ Copyright © 2023 + + + + + + diff --git a/src/c#/GeneralUpdate.Maui.OSS/GeneralUpdate.Maui.OSS.csproj b/src/c#/GeneralUpdate.Maui.OSS/GeneralUpdate.Maui.OSS.csproj index fde0276d1c3d49a8e44a193339cd9413bbd91e23..ed412e67912256d73b7737f59929e2b30f9fab17 100644 --- a/src/c#/GeneralUpdate.Maui.OSS/GeneralUpdate.Maui.OSS.csproj +++ b/src/c#/GeneralUpdate.Maui.OSS/GeneralUpdate.Maui.OSS.csproj @@ -28,18 +28,33 @@ + + + + + + + + + + + + + + + diff --git a/src/c#/GeneralUpdate.Maui.OSS/GeneralUpdateOSS.cs b/src/c#/GeneralUpdate.Maui.OSS/GeneralUpdateOSS.cs index 5523a4f53e21a45103ebf80a8b2c0165206617ac..30e16c3cd368b0beefa477221bb3535ea67187fd 100644 --- a/src/c#/GeneralUpdate.Maui.OSS/GeneralUpdateOSS.cs +++ b/src/c#/GeneralUpdate.Maui.OSS/GeneralUpdateOSS.cs @@ -31,27 +31,21 @@ namespace GeneralUpdate.Maui.OSS /// Updated version configuration file name. /// Method entry parameter is null exception. public static async Task Start(ParamsAndroid parameter) where TStrategy : AbstractStrategy, new() - { - await BaseStart(parameter); - } + => await BaseStart(parameter); /// /// Monitor download progress. /// /// public static void AddListenerDownloadProcess(Action callbackAction) - { - AddListener(callbackAction); - } + => AddListener(callbackAction); /// /// Listen for internal exception information. /// /// public static void AddListenerException(Action callbackAction) - { - AddListener(callbackAction); - } + => AddListener(callbackAction); #endregion Public Methods diff --git a/src/c#/GeneralUpdate.Single/GeneralUpdate.Single.csproj b/src/c#/GeneralUpdate.Single/GeneralUpdate.Single.csproj deleted file mode 100644 index 246b607e608b0f0e5f5410ad51ff7c4b24233c4e..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Single/GeneralUpdate.Single.csproj +++ /dev/null @@ -1,92 +0,0 @@ - - - - - Debug - AnyCPU - {57300FDD-58E9-489E-BF2E-C69A87938845} - Library - GeneralUpdate.Single - GeneralUpdate.Single - v4.8 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - true - - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - 4.0 - - - - - - - - PreserveNewest - .\lib\net45 - - - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Single/GeneralUpdate.ico b/src/c#/GeneralUpdate.Single/GeneralUpdate.ico deleted file mode 100644 index 7cb4a86c1bbf84baf7b783ab21b4a7e1cf700455..0000000000000000000000000000000000000000 Binary files a/src/c#/GeneralUpdate.Single/GeneralUpdate.ico and /dev/null differ diff --git a/src/c#/GeneralUpdate.Single/Properties/AssemblyInfo.cs b/src/c#/GeneralUpdate.Single/Properties/AssemblyInfo.cs deleted file mode 100644 index adb2a013d9454de45a13d07e405edd8f6b19e6a0..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Single/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; -using System.Windows; - -// 有关程序集的一般信息由以下 -// 控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("GeneralUpdate.Single")] -[assembly: AssemblyDescription("Make your program a singleton.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("juster.zhu WELL-E")] -[assembly: AssemblyProduct("GeneralUpdate.Single")] -[assembly: AssemblyCopyright("Copyright © 2023")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 会使此程序集中的类型 -//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 -//请将此类型的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -//若要开始生成可本地化的应用程序,请设置 -//.csproj 文件中的 CultureYouAreCodingWith -//例如,如果您在源文件中使用的是美国英语, -//使用的是美国英语,请将 设置为 en-US。 然后取消 -//对以下 NeutralResourceLanguage 特性的注释。 更新 -//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。 - -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, //主题特定资源词典所处位置 - //(未在页面中找到资源时使用, - //或应用程序资源字典中找到时使用) - ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置 - //(未在页面中找到资源时使用, - //、应用程序或任何主题专用资源字典中找到时使用) -)] - -// 程序集的版本信息由下列四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 -//通过使用 "*",如下所示: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Single/Properties/Resources.Designer.cs b/src/c#/GeneralUpdate.Single/Properties/Resources.Designer.cs deleted file mode 100644 index 374d36e6cb5affb41f1cb9043aa6dd893cbea0b6..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Single/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace GeneralUpdate.Single.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GeneralUpdate.Single.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/src/c#/GeneralUpdate.Single/Properties/Resources.resx b/src/c#/GeneralUpdate.Single/Properties/Resources.resx deleted file mode 100644 index af7dbebbacef595e3089c01c05671016c21a8304..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Single/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Single/Properties/Settings.Designer.cs b/src/c#/GeneralUpdate.Single/Properties/Settings.Designer.cs deleted file mode 100644 index e8ccde90ae161a908fcf1331c1fef34524a6c137..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Single/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace GeneralUpdate.Single.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/src/c#/GeneralUpdate.Single/Properties/Settings.settings b/src/c#/GeneralUpdate.Single/Properties/Settings.settings deleted file mode 100644 index 033d7a5e9e2266753180f4e3a9299f575046701e..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Single/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Single/SingleInstance.cs b/src/c#/GeneralUpdate.Single/SingleInstance.cs deleted file mode 100644 index 59bc1c7ef1a0643e1b16c49b4b0d2a9b15a8a009..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Single/SingleInstance.cs +++ /dev/null @@ -1,489 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// -// This class checks to make sure that only one instance of -// this application is running at a time. -// -//----------------------------------------------------------------------- - -namespace GeneralUpdate.Core.Utils -{ - using System; - using System.Collections; - using System.Collections.Generic; - using System.ComponentModel; - using System.IO; - using System.Runtime.InteropServices; - using System.Runtime.Remoting; - using System.Runtime.Remoting.Channels; - using System.Runtime.Remoting.Channels.Ipc; - using System.Runtime.Serialization.Formatters; - using System.Security; - using System.Threading; - using System.Windows; - using System.Windows.Threading; - - internal enum WM - { - NULL = 0x0000, - CREATE = 0x0001, - DESTROY = 0x0002, - MOVE = 0x0003, - SIZE = 0x0005, - ACTIVATE = 0x0006, - SETFOCUS = 0x0007, - KILLFOCUS = 0x0008, - ENABLE = 0x000A, - SETREDRAW = 0x000B, - SETTEXT = 0x000C, - GETTEXT = 0x000D, - GETTEXTLENGTH = 0x000E, - PAINT = 0x000F, - CLOSE = 0x0010, - QUERYENDSESSION = 0x0011, - QUIT = 0x0012, - QUERYOPEN = 0x0013, - ERASEBKGND = 0x0014, - SYSCOLORCHANGE = 0x0015, - SHOWWINDOW = 0x0018, - ACTIVATEAPP = 0x001C, - SETCURSOR = 0x0020, - MOUSEACTIVATE = 0x0021, - CHILDACTIVATE = 0x0022, - QUEUESYNC = 0x0023, - GETMINMAXINFO = 0x0024, - - WINDOWPOSCHANGING = 0x0046, - WINDOWPOSCHANGED = 0x0047, - - CONTEXTMENU = 0x007B, - STYLECHANGING = 0x007C, - STYLECHANGED = 0x007D, - DISPLAYCHANGE = 0x007E, - GETICON = 0x007F, - SETICON = 0x0080, - NCCREATE = 0x0081, - NCDESTROY = 0x0082, - NCCALCSIZE = 0x0083, - NCHITTEST = 0x0084, - NCPAINT = 0x0085, - NCACTIVATE = 0x0086, - GETDLGCODE = 0x0087, - SYNCPAINT = 0x0088, - NCMOUSEMOVE = 0x00A0, - NCLBUTTONDOWN = 0x00A1, - NCLBUTTONUP = 0x00A2, - NCLBUTTONDBLCLK = 0x00A3, - NCRBUTTONDOWN = 0x00A4, - NCRBUTTONUP = 0x00A5, - NCRBUTTONDBLCLK = 0x00A6, - NCMBUTTONDOWN = 0x00A7, - NCMBUTTONUP = 0x00A8, - NCMBUTTONDBLCLK = 0x00A9, - - SYSKEYDOWN = 0x0104, - SYSKEYUP = 0x0105, - SYSCHAR = 0x0106, - SYSDEADCHAR = 0x0107, - COMMAND = 0x0111, - SYSCOMMAND = 0x0112, - - MOUSEMOVE = 0x0200, - LBUTTONDOWN = 0x0201, - LBUTTONUP = 0x0202, - LBUTTONDBLCLK = 0x0203, - RBUTTONDOWN = 0x0204, - RBUTTONUP = 0x0205, - RBUTTONDBLCLK = 0x0206, - MBUTTONDOWN = 0x0207, - MBUTTONUP = 0x0208, - MBUTTONDBLCLK = 0x0209, - MOUSEWHEEL = 0x020A, - XBUTTONDOWN = 0x020B, - XBUTTONUP = 0x020C, - XBUTTONDBLCLK = 0x020D, - MOUSEHWHEEL = 0x020E, - - CAPTURECHANGED = 0x0215, - - ENTERSIZEMOVE = 0x0231, - EXITSIZEMOVE = 0x0232, - - IME_SETCONTEXT = 0x0281, - IME_NOTIFY = 0x0282, - IME_CONTROL = 0x0283, - IME_COMPOSITIONFULL = 0x0284, - IME_SELECT = 0x0285, - IME_CHAR = 0x0286, - IME_REQUEST = 0x0288, - IME_KEYDOWN = 0x0290, - IME_KEYUP = 0x0291, - - NCMOUSELEAVE = 0x02A2, - - DWMCOMPOSITIONCHANGED = 0x031E, - DWMNCRENDERINGCHANGED = 0x031F, - DWMCOLORIZATIONCOLORCHANGED = 0x0320, - DWMWINDOWMAXIMIZEDCHANGE = 0x0321, - - #region Windows 7 - - DWMSENDICONICTHUMBNAIL = 0x0323, - DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326, - - #endregion Windows 7 - - USER = 0x0400, - - // This is the hard-coded message value used by WinForms for Shell_NotifyIcon. - // It's relatively safe to reuse. - TRAYMOUSEMESSAGE = 0x800, //WM_USER + 1024 - - APP = 0x8000, - } - - [SuppressUnmanagedCodeSecurity] - internal static class NativeMethods - { - /// - /// Delegate declaration that matches WndProc signatures. - /// - public delegate IntPtr MessageHandler(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled); - - [DllImport("shell32.dll", EntryPoint = "CommandLineToArgvW", CharSet = CharSet.Unicode)] - private static extern IntPtr _CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string cmdLine, out int numArgs); - - [DllImport("kernel32.dll", EntryPoint = "LocalFree", SetLastError = true)] - private static extern IntPtr _LocalFree(IntPtr hMem); - - public static string[] CommandLineToArgvW(string cmdLine) - { - IntPtr argv = IntPtr.Zero; - try - { - int numArgs = 0; - - argv = _CommandLineToArgvW(cmdLine, out numArgs); - if (argv == IntPtr.Zero) - { - throw new Win32Exception(); - } - var result = new string[numArgs]; - - for (int i = 0; i < numArgs; i++) - { - IntPtr currArg = Marshal.ReadIntPtr(argv, i * Marshal.SizeOf(typeof(IntPtr))); - result[i] = Marshal.PtrToStringUni(currArg); - } - - return result; - } - finally - { - IntPtr p = _LocalFree(argv); - // Otherwise LocalFree failed. - // Assert.AreEqual(IntPtr.Zero, p); - } - } - } - - public interface ISingleInstanceApp - { - bool SignalExternalCommandLineArgs(IList args); - } - - /// - /// This class checks to make sure that only one instance of - /// this application is running at a time. - /// - /// - /// Note: this class should be used with some caution, because it does no - /// security checking. For example, if one instance of an app that uses this class - /// is running as Administrator, any other instance, even if it is not - /// running as Administrator, can activate it with command line arguments. - /// For most apps, this will not be much of an issue. - /// - public static class SingleInstance - where TApplication : Application, ISingleInstanceApp - { - #region Private Fields - - /// - /// String delimiter used in channel names. - /// - private const string Delimiter = ":"; - - /// - /// Suffix to the channel name. - /// - private const string ChannelNameSuffix = "SingeInstanceIPCChannel"; - - /// - /// Remote service name. - /// - private const string RemoteServiceName = "SingleInstanceApplicationService"; - - /// - /// IPC protocol used (string). - /// - private const string IpcProtocol = "ipc://"; - - /// - /// Application mutex. - /// - private static Mutex singleInstanceMutex; - - /// - /// IPC channel for communications. - /// - private static IpcServerChannel channel; - - /// - /// List of command line arguments for the application. - /// - private static IList commandLineArgs; - - #endregion Private Fields - - #region Public Properties - - /// - /// Gets list of command line arguments for the application. - /// - public static IList CommandLineArgs - { - get { return commandLineArgs; } - } - - #endregion Public Properties - - #region Public Methods - - /// - /// Checks if the instance of the application attempting to start is the first instance. - /// If not, activates the first instance. - /// - /// True if this is the first instance of the application. - public static bool InitializeAsFirstInstance(string uniqueName) - { - commandLineArgs = GetCommandLineArgs(uniqueName); - - // Build unique application Id and the IPC channel name. - string applicationIdentifier = uniqueName + Environment.UserName; - - string channelName = String.Concat(applicationIdentifier, Delimiter, ChannelNameSuffix); - - // Create mutex based on unique application Id to check if this is the first instance of the application. - bool firstInstance; - singleInstanceMutex = new Mutex(true, applicationIdentifier, out firstInstance); - if (firstInstance) - { - CreateRemoteService(channelName); - } - else - { - SignalFirstInstance(channelName, commandLineArgs); - } - - return firstInstance; - } - - /// - /// Cleans up single-instance code, clearing shared resources, mutexes, etc. - /// - public static void Cleanup() - { - if (singleInstanceMutex != null) - { - singleInstanceMutex.Close(); - singleInstanceMutex = null; - } - - if (channel != null) - { - ChannelServices.UnregisterChannel(channel); - channel = null; - } - } - - #endregion Public Methods - - #region Private Methods - - /// - /// Gets command line args - for ClickOnce deployed applications, command line args may not be passed directly, they have to be retrieved. - /// - /// List of command line arg strings. - private static IList GetCommandLineArgs(string uniqueApplicationName) - { - string[] args = null; - if (AppDomain.CurrentDomain.ActivationContext == null) - { - // The application was not clickonce deployed, get args from standard API's - args = Environment.GetCommandLineArgs(); - } - else - { - // The application was clickonce deployed - // Clickonce deployed apps cannot recieve traditional commandline arguments - // As a workaround commandline arguments can be written to a shared location before - // the app is launched and the app can obtain its commandline arguments from the - // shared location - string appFolderPath = Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), uniqueApplicationName); - - string cmdLinePath = Path.Combine(appFolderPath, "cmdline.txt"); - if (File.Exists(cmdLinePath)) - { - try - { - using (TextReader reader = new StreamReader(cmdLinePath, System.Text.Encoding.Unicode)) - { - args = NativeMethods.CommandLineToArgvW(reader.ReadToEnd()); - } - - File.Delete(cmdLinePath); - } - catch (IOException) - { - } - } - } - - if (args == null) - { - args = new string[] { }; - } - - return new List(args); - } - - /// - /// Creates a remote service for communication. - /// - /// Application's IPC channel name. - private static void CreateRemoteService(string channelName) - { - BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); - serverProvider.TypeFilterLevel = TypeFilterLevel.Full; - IDictionary props = new Dictionary(); - - props["name"] = channelName; - props["portName"] = channelName; - props["exclusiveAddressUse"] = "false"; - - // Create the IPC Server channel with the channel properties - channel = new IpcServerChannel(props, serverProvider); - - // Register the channel with the channel services - ChannelServices.RegisterChannel(channel, true); - - // Expose the remote service with the REMOTE_SERVICE_NAME - IPCRemoteService remoteService = new IPCRemoteService(); - RemotingServices.Marshal(remoteService, RemoteServiceName); - } - - /// - /// Creates a client channel and obtains a reference to the remoting service exposed by the server - - /// in this case, the remoting service exposed by the first instance. Calls a function of the remoting service - /// class to pass on command line arguments from the second instance to the first and cause it to activate itself. - /// - /// Application's IPC channel name. - /// - /// Command line arguments for the second instance, passed to the first instance to take appropriate action. - /// - private static void SignalFirstInstance(string channelName, IList args) - { - IpcClientChannel secondInstanceChannel = new IpcClientChannel(); - ChannelServices.RegisterChannel(secondInstanceChannel, true); - - string remotingServiceUrl = IpcProtocol + channelName + "/" + RemoteServiceName; - - // Obtain a reference to the remoting service exposed by the server i.e the first instance of the application - IPCRemoteService firstInstanceRemoteServiceReference = (IPCRemoteService)RemotingServices.Connect(typeof(IPCRemoteService), remotingServiceUrl); - - // Check that the remote service exists, in some cases the first instance may not yet have created one, in which case - // the second instance should just exit - if (firstInstanceRemoteServiceReference != null) - { - // Invoke a method of the remote service exposed by the first instance passing on the command line - // arguments and causing the first instance to activate itself - try - { - firstInstanceRemoteServiceReference.InvokeFirstInstance(args); - } - catch (Exception) - { - // ignored - } - } - } - - /// - /// Callback for activating first instance of the application. - /// - /// Callback argument. - /// Always null. - private static object ActivateFirstInstanceCallback(object arg) - { - // Get command line args to be passed to first instance - IList args = arg as IList; - ActivateFirstInstance(args); - return null; - } - - /// - /// Activates the first instance of the application with arguments from a second instance. - /// - /// List of arguments to supply the first instance of the application. - private static void ActivateFirstInstance(IList args) - { - // Set main window state and process command line args - if (Application.Current == null) - { - return; - } - - ((TApplication)Application.Current).SignalExternalCommandLineArgs(args); - } - - #endregion Private Methods - - #region Private Classes - - /// - /// Remoting service class which is exposed by the server i.e the first instance and called by the second instance - /// to pass on the command line arguments to the first instance and cause it to activate itself. - /// - private class IPCRemoteService : MarshalByRefObject - { - /// - /// Activates the first instance of the application. - /// - /// List of arguments to pass to the first instance. - public void InvokeFirstInstance(IList args) - { - if (Application.Current != null) - { - // Do an asynchronous call to ActivateFirstInstance function - Application.Current.Dispatcher.BeginInvoke( - DispatcherPriority.Normal, new DispatcherOperationCallback(SingleInstance.ActivateFirstInstanceCallback), args); - } - } - - /// - /// Remoting Object's ease expires after every 5 minutes by default. We need to override the InitializeLifetimeService class - /// to ensure that lease never expires. - /// - /// Always null. - public override object InitializeLifetimeService() - { - return null; - } - } - - #endregion Private Classes - } -} \ No newline at end of file diff --git a/src/c#/GeneralUpdate.SystemService/GeneralUpdate.SystemService.csproj b/src/c#/GeneralUpdate.SystemService/GeneralUpdate.SystemService.csproj index 5018bdeed9c04b64971760d989317cb60fe43ae4..c6105f47e0b9feafa5f6ef4ebef31271563710b9 100644 --- a/src/c#/GeneralUpdate.SystemService/GeneralUpdate.SystemService.csproj +++ b/src/c#/GeneralUpdate.SystemService/GeneralUpdate.SystemService.csproj @@ -15,7 +15,6 @@ - @@ -49,7 +48,6 @@ - @@ -60,6 +58,5 @@ - diff --git a/src/c#/GeneralUpdate.SystemService/Utrils/.gitkeep b/src/c#/GeneralUpdate.SystemService/Utrils/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/c#/GeneralUpdate.Zip/G7z/General7z.cs b/src/c#/GeneralUpdate.Zip/CompressProvider/Compress7z.cs similarity index 97% rename from src/c#/GeneralUpdate.Zip/G7z/General7z.cs rename to src/c#/GeneralUpdate.Zip/CompressProvider/Compress7z.cs index 848d344932feee7a0d1c6ac3a02c9910be97f1ec..57ea61ff6f082ceae714fcd693c3d6131894858b 100644 --- a/src/c#/GeneralUpdate.Zip/G7z/General7z.cs +++ b/src/c#/GeneralUpdate.Zip/CompressProvider/Compress7z.cs @@ -10,7 +10,7 @@ using System.IO; using System.Linq; using System.Text; -namespace GeneralUpdate.Zip.G7z +namespace GeneralUpdate.Zip.CompressProvider { /// /// Source address : https://github.com/adamhathcock/sharpcompress/blob/master/tests/SharpCompress.Test/WriterTests.cs @@ -18,7 +18,7 @@ namespace GeneralUpdate.Zip.G7z /// Tribute to the original author . /// Secondary developer : Juster Z /// - public class General7z : BaseCompress + public class Compress7z : BaseCompress { private string _destinationPath; private Encoding _encoding; diff --git a/src/c#/GeneralUpdate.Zip/GZip/GeneralZip.cs b/src/c#/GeneralUpdate.Zip/CompressProvider/CompressZip.cs similarity index 99% rename from src/c#/GeneralUpdate.Zip/GZip/GeneralZip.cs rename to src/c#/GeneralUpdate.Zip/CompressProvider/CompressZip.cs index ea43a7a33ac576b4ed02d25068b128a0e6b651b8..88840a034c10ae2a64120de052419b4c7bdcde00 100644 --- a/src/c#/GeneralUpdate.Zip/GZip/GeneralZip.cs +++ b/src/c#/GeneralUpdate.Zip/CompressProvider/CompressZip.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; -namespace GeneralUpdate.Zip.GZip +namespace GeneralUpdate.Zip.CompressProvider { /// /// Source address : https://www.cnblogs.com/Chary/p/No0000DF.html @@ -15,7 +15,7 @@ namespace GeneralUpdate.Zip.GZip /// Tribute to the original author . /// Secondary developer : Juster Z /// - public class GeneralZip : BaseCompress + public class CompressZip : BaseCompress { private string _destinationPath; private bool _includeBaseDirectory; diff --git a/src/c#/GeneralUpdate.Zip/GeneralUpdate.Zip.csproj b/src/c#/GeneralUpdate.Zip/GeneralUpdate.Zip.csproj index d1e8136582e880007cd1cc73bdd185bea237513d..a820ab857381192e9b4fbdecf0bcd47382eb5d4c 100644 --- a/src/c#/GeneralUpdate.Zip/GeneralUpdate.Zip.csproj +++ b/src/c#/GeneralUpdate.Zip/GeneralUpdate.Zip.csproj @@ -14,12 +14,6 @@ https://github.com/JusterZhu/GeneralUpdate - - - - - - diff --git a/src/c#/GeneralUpdate.Zip/GeneralUpdate.Zip.nuspec b/src/c#/GeneralUpdate.Zip/GeneralUpdate.Zip.nuspec deleted file mode 100644 index f7762d5ebbe259380ec3eb983a61b408cfb6e8cf..0000000000000000000000000000000000000000 --- a/src/c#/GeneralUpdate.Zip/GeneralUpdate.Zip.nuspec +++ /dev/null @@ -1,18 +0,0 @@ - - - - $id$ - $version$ - $title$ - $author$ - $author$ - MIT - https://github.com/WELL-E/AutoUpdater.git - https://raw.githubusercontent.com/NuGet/Samples/master/PackageIconNuspecExample/icon.png - false - $description$ - Decompress the compressed file with progress notification. - Copyright 2021 - zip - - \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Zip/GeneralZipFactory.cs b/src/c#/GeneralUpdate.Zip/GeneralZipFactory.cs index 594daa30184931c8833419d68d9c229063564466..2edf7525330493ba7d4c3c8007204531a253bb21 100644 --- a/src/c#/GeneralUpdate.Zip/GeneralZipFactory.cs +++ b/src/c#/GeneralUpdate.Zip/GeneralZipFactory.cs @@ -1,7 +1,6 @@ -using GeneralUpdate.Zip.Events; +using GeneralUpdate.Zip.CompressProvider; +using GeneralUpdate.Zip.Events; using GeneralUpdate.Zip.Factory; -using GeneralUpdate.Zip.G7z; -using GeneralUpdate.Zip.GZip; using System; using System.Text; @@ -47,12 +46,12 @@ namespace GeneralUpdate.Zip switch (type) { case OperationType.GZip: - _operation = new GeneralZip(); + _operation = new CompressZip(); _operation.Configs(name, sourcePath, destinationPath, encoding, includeBaseDirectory); break; case OperationType.G7z: - _operation = new General7z(); + _operation = new Compress7z(); _operation.Configs(name, sourcePath, destinationPath, encoding, includeBaseDirectory); break; } @@ -84,27 +83,13 @@ namespace GeneralUpdate.Zip public IFactory CreateZip() { - try - { - _operation.CreateZip(); - } - catch (Exception ex) - { - throw new Exception($"'CreateZip' exception : {ex.Message} .", ex.InnerException); - } + _operation?.CreateZip(); return this; } public IFactory UnZip() { - try - { - _operation.UnZip(); - } - catch (Exception ex) - { - throw new Exception($"'CreateOperate' exception : {ex.Message} .", ex.InnerException); - } + _operation?.UnZip(); return this; } } diff --git a/src/c#/GeneralUpdate.Zip/nuget.exe b/src/c#/GeneralUpdate.Zip/nuget.exe deleted file mode 100644 index 3ae0060a9ddfb3ad505a82c642a51c1186f6801b..0000000000000000000000000000000000000000 Binary files a/src/c#/GeneralUpdate.Zip/nuget.exe and /dev/null differ diff --git a/src/c#/GeneralUpdate.sln b/src/c#/GeneralUpdate.sln index 0bcd9f746d5a22357b24f0e7ee4943f4410ed100..e74b7b14d1205b04869cc720b4e16fd652ff2552 100644 --- a/src/c#/GeneralUpdate.sln +++ b/src/c#/GeneralUpdate.sln @@ -7,8 +7,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{91F059E6-7AD EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeneralUpdate.Core", "GeneralUpdate.Core\GeneralUpdate.Core.csproj", "{35BFF228-5EE4-49A6-B721-FB0122E967A0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeneralUpdate.Single", "GeneralUpdate.Single\GeneralUpdate.Single.csproj", "{57300FDD-58E9-489E-BF2E-C69A87938845}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeneralUpdate.Zip", "GeneralUpdate.Zip\GeneralUpdate.Zip.csproj", "{D94882E1-55A7-4787-B049-265F52DC576E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeneralUpdate.ClientCore", "GeneralUpdate.ClientCore\GeneralUpdate.ClientCore.csproj", "{BAEFF926-6B2C-46F1-BB73-AA2AB1355565}" @@ -37,10 +35,6 @@ Global {35BFF228-5EE4-49A6-B721-FB0122E967A0}.Debug|Any CPU.Build.0 = Debug|Any CPU {35BFF228-5EE4-49A6-B721-FB0122E967A0}.Release|Any CPU.ActiveCfg = Release|Any CPU {35BFF228-5EE4-49A6-B721-FB0122E967A0}.Release|Any CPU.Build.0 = Release|Any CPU - {57300FDD-58E9-489E-BF2E-C69A87938845}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {57300FDD-58E9-489E-BF2E-C69A87938845}.Debug|Any CPU.Build.0 = Debug|Any CPU - {57300FDD-58E9-489E-BF2E-C69A87938845}.Release|Any CPU.ActiveCfg = Release|Any CPU - {57300FDD-58E9-489E-BF2E-C69A87938845}.Release|Any CPU.Build.0 = Release|Any CPU {D94882E1-55A7-4787-B049-265F52DC576E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D94882E1-55A7-4787-B049-265F52DC576E}.Debug|Any CPU.Build.0 = Debug|Any CPU {D94882E1-55A7-4787-B049-265F52DC576E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -81,7 +75,6 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {35BFF228-5EE4-49A6-B721-FB0122E967A0} = {91F059E6-7AD3-4FB7-9604-30A7849C6EFF} - {57300FDD-58E9-489E-BF2E-C69A87938845} = {91F059E6-7AD3-4FB7-9604-30A7849C6EFF} {D94882E1-55A7-4787-B049-265F52DC576E} = {91F059E6-7AD3-4FB7-9604-30A7849C6EFF} {BAEFF926-6B2C-46F1-BB73-AA2AB1355565} = {91F059E6-7AD3-4FB7-9604-30A7849C6EFF} {40BDA496-7614-4213-92D0-3B1B187675D3} = {91F059E6-7AD3-4FB7-9604-30A7849C6EFF}