diff --git a/README.md b/README.md index bc33e58cec330bb5ae1d3a5a21e459cf633267fe..83bff3efbd3057a0fdf8c85dbe614e9936f81f42 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ | 黑名单 | 支持 | 在更新过程中会跳过黑名单中的文件列表和文件扩展名列表。 | | OSS | 支持 | 极简化更新,是一套独立的更新机制。只需要在文件服务器中放置version.json的版本配置文件。组件会根据配置文件中的版本信息进行更新下载。(支持Windows,MAUI Android) | | 回滚 | 待测试 | 逐版本更新时会备份每个版本,如果更新失败则逐版本回滚。 | -| 驱动更新 | 待测试 | 逐版本更新时会备份每个版本的驱动文件(.inf),如果更新失败则逐版本回滚。 | +| 驱动更新 | 支持 | 逐版本更新时会备份每个版本的驱动文件(.inf),如果更新失败则逐版本回滚。 | | 遗言 | 待测试 | 开机时和升级时会检查升级是否成功,如果失败则根据遗言还原之前的备份。遗言是更新之前就已经自动创建在C:\generalupdate_willmessages目录下的will_message.json文件。will_message.json的内容是持久化回滚备份的文件目录相关信息。(需要部署GeneralUpdate.SystemService系统服务) | | 自定义方法列表 | 待测试 | 注入一个自定义方法集合,该集合会在更新启动前执行。执行自定义方法列表如果出现任何异常,将通过异常订阅通知。(推荐在更新之前检查当前软件环境) | diff --git a/README_en.md b/README_en.md index d0ffb77d1a4efe46689fe5e74b4fb2723171a622..7687904ba76abd85f62f71439d59cf6f39a38377 100644 --- a/README_en.md +++ b/README_en.md @@ -27,7 +27,7 @@ | Black list | yes | Files and file extensions from the blacklist are skipped during the update process. | | OSS | yes | Minimal updates require only the version configuration file of version.json to be placed on the file server. Components are updated and downloaded based on the version information in the configuration file.(Supported windows,MAUI Android) | | Restore | test | Each version is backed up during a version-by-version update and rolled back version-by-version if the update fails. | -| Driver upgrade | test | The driver file (.INF) of each version is backed up during the version-by-version update and is rolled back version-by-version if the update fails. | +| Driver upgrade | yes | The driver file (.INF) of each version is backed up during the version-by-version update and is rolled back version-by-version if the update fails. | | Will message | test | The upgrade is checked for success at boot and upgrade, and if it fails, the previous backup is restored according to the last word. The last word is that the will_message.json file in the C:\generalupdate_willmessages directory was automatically created before the update. will_message.json is about the file directory of the persistent rollback backup.(need to deploy GeneralUpdate. SystemService system service) | | A list of custom methods | test | Inject a custom collection of methods that are executed before the update starts. Execute a custom method list, and if there are any exceptions, you will be notified by exception subscription.(It is recommended to check the current software environment before updating) | diff --git a/src/c#/GeneralUpdate.ClientCore/GeneralClientBootstrap.cs b/src/c#/GeneralUpdate.ClientCore/GeneralClientBootstrap.cs index b20053c2457a0719527e89443d948428605f3036..555e18f48c92ebb4f7718f85a739b5815d605c24 100644 --- a/src/c#/GeneralUpdate.ClientCore/GeneralClientBootstrap.cs +++ b/src/c#/GeneralUpdate.ClientCore/GeneralClientBootstrap.cs @@ -13,6 +13,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Security; using System.Threading.Tasks; namespace GeneralUpdate.ClientCore @@ -54,6 +55,7 @@ namespace GeneralUpdate.ClientCore private async Task BaseLaunch() { + ClearEnvironmentVariable(); await ExecuteCustomOptions(); var versionService = new VersionService(); var mainResp = await versionService.ValidationVersion(Packet.MainUpdateUrl); @@ -244,6 +246,25 @@ namespace GeneralUpdate.ClientCore } } + /// + /// The values passed between processes during previous updates are cleared when the client starts. + /// + private void ClearEnvironmentVariable() + { + try + { + Environment.SetEnvironmentVariable("ProcessBase64", null, EnvironmentVariableTarget.Machine); + } + catch (SecurityException ex) + { + Trace.WriteLine($"Error: You do not have sufficient permissions to delete this environment variable.{ex}"); + } + catch (ArgumentException ex) + { + Trace.WriteLine($"Error: The environment variable name is invalid. {ex}"); + } + } + #endregion Private Methods } } \ No newline at end of file diff --git a/src/c#/GeneralUpdate.ClientCore/GeneralUpdate.ClientCore.csproj b/src/c#/GeneralUpdate.ClientCore/GeneralUpdate.ClientCore.csproj index 9a5012e291376521dd17c060ec98d339dc933127..156e66dd51ba4da35e14fc0dc79c1b84483d3d3d 100644 --- a/src/c#/GeneralUpdate.ClientCore/GeneralUpdate.ClientCore.csproj +++ b/src/c#/GeneralUpdate.ClientCore/GeneralUpdate.ClientCore.csproj @@ -107,6 +107,7 @@ + diff --git a/src/c#/GeneralUpdate.Core/Driver/DriverProcessor.cs b/src/c#/GeneralUpdate.Core/Driver/DriverProcessor.cs index 9d02c28ad953d386fb824354478616f0c1fc8826..88b254639c2113b7674140d8ae8ef785ac1bd75d 100644 --- a/src/c#/GeneralUpdate.Core/Driver/DriverProcessor.cs +++ b/src/c#/GeneralUpdate.Core/Driver/DriverProcessor.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; namespace GeneralUpdate.Core.Driver { @@ -19,6 +20,8 @@ namespace GeneralUpdate.Core.Driver /// public void ProcessCommands() { + if (!_commands.Any()) return; + /* * This section describes the PnPUtil command. * https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/pnputil-command-syntax diff --git a/src/c#/GeneralUpdate.Core/Driver/InstallDriverCommand.cs b/src/c#/GeneralUpdate.Core/Driver/InstallDriverCommand.cs index 9e7a61f0c1a6c4b99cdc25988f200be5af3ee40e..41c3f53cdc23a159253d610efac6f7c7cf0ef646 100644 --- a/src/c#/GeneralUpdate.Core/Driver/InstallDriverCommand.cs +++ b/src/c#/GeneralUpdate.Core/Driver/InstallDriverCommand.cs @@ -4,6 +4,9 @@ using System.Text; namespace GeneralUpdate.Core.Driver { + /// + /// Install the new driver, and if the installation fails, the backup is automatically restored. + /// public class InstallDriverCommand : IDriverCommand { private DriverInformation _information; diff --git a/src/c#/GeneralUpdate.Core/Pipelines/Middleware/DriveMiddleware.cs b/src/c#/GeneralUpdate.Core/Pipelines/Middleware/DriveMiddleware.cs index 701f07a5e69cb7ad386dd4eb0a52d99966a91057..018f02c8b870aec25640c30489f7c20be94adbdd 100644 --- a/src/c#/GeneralUpdate.Core/Pipelines/Middleware/DriveMiddleware.cs +++ b/src/c#/GeneralUpdate.Core/Pipelines/Middleware/DriveMiddleware.cs @@ -1,4 +1,7 @@ -using System.IO; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Threading.Tasks; using GeneralUpdate.Core.Driver; using GeneralUpdate.Core.Pipelines.Context; @@ -12,20 +15,66 @@ namespace GeneralUpdate.Core.Pipelines.Middleware { public async Task InvokeAsync(BaseContext context, MiddlewareStack stack) { + var drivers = GetAllDriverDirectories(context.TargetPath); + var information = new DriverInformation.Builder() .SetInstallDirectory(Path.Combine(context.SourcePath,context.Version.ToString())) + //TODO: TargetPath to CachePath .SetOutPutDirectory(Path.Combine(context.TargetPath,context.Version.ToString())) - .SetDriverNames(null) + .SetDriverNames(drivers) .Build(); var processor = new DriverProcessor(); - // Backup driver. processor.AddCommand(new BackupDriverCommand(information)); - // Install the new driver, and if the installation fails, the backup is automatically restored. + processor.AddCommand(new DeleteDriverCommand(information)); processor.AddCommand(new InstallDriverCommand(information)); processor.ProcessCommands(); + var node = stack.Pop(); if (node != null) await node.Next.Invoke(context, stack); } + + /// + /// Identifies all folders containing driver files in the specified directory and returns the directory collection. + /// + /// + /// + private List GetAllDriverDirectories(string path) + { + var driverDirectories = new HashSet(); + try + { + foreach (string filePath in Directory.GetFiles(path)) + { + if (IsDriverFile(filePath)) + { + driverDirectories.Add(filePath); + } + } + + foreach (string directory in Directory.GetDirectories(path)) + { + driverDirectories.UnionWith(GetAllDriverDirectories(directory)); + } + } + catch (UnauthorizedAccessException) + { + Trace.WriteLine("No access directory:" + path); + } + catch (PathTooLongException) + { + Trace.WriteLine("Path overlength:" + path); + } + + return new List(driverDirectories); + } + + /// + /// Match the driver installation boot file. + /// + /// + /// + private bool IsDriverFile(string filePath)=> + string.Equals(Path.GetExtension(filePath), ".inf", StringComparison.OrdinalIgnoreCase); } } \ No newline at end of file diff --git a/src/c#/GeneralUpdate.Core/Pipelines/Middleware/MiddlewareExtensions.cs b/src/c#/GeneralUpdate.Core/Pipelines/Middleware/MiddlewareExtensions.cs index 6fab56078c773e99418c6884b63fb8c890415c89..4ffa3b163537e8da1a9a21c4b67d7e49f1bfbf3a 100644 --- a/src/c#/GeneralUpdate.Core/Pipelines/Middleware/MiddlewareExtensions.cs +++ b/src/c#/GeneralUpdate.Core/Pipelines/Middleware/MiddlewareExtensions.cs @@ -32,7 +32,7 @@ namespace GeneralUpdate.Core.Pipelines.Middleware MethodInfo invokeMethod = null; foreach (var method in methods) { - if (string.Equals(method.Name, InvokeAsyncMethodName, StringComparison.Ordinal)) + if (string.Equals(method.Name, InvokeAsyncMethodName, StringComparison.OrdinalIgnoreCase)) { if (method == null) throw new InvalidOperationException(InvokeAsyncMethodName); invokeMethod = method;