From 17488a51f16030f8887e1e4e212de22b9c65bbc4 Mon Sep 17 00:00:00 2001 From: Juster Zhu Date: Sat, 23 Dec 2023 19:56:39 +0800 Subject: [PATCH] feature: Test and modify the driver update function --- src/c#/GeneralUpdate.Client/Program.cs | 2 +- .../Driver/BackupDriverCommand.cs | 34 +++++++++++++------ .../Driver/CommandExecutor.cs | 10 +++--- .../Driver/DeleteDriverCommand.cs | 23 +++++++++++++ .../Driver/DriverInformation.cs | 6 ++-- .../Driver/DriverProcessor.cs | 5 ++- .../Driver/InstallDriverCommand.cs | 29 ++++++++++------ .../Driver/RestoreDriverCommand.cs | 31 +++++++++++------ src/c#/TestCore/TestCore.csproj | 4 +++ src/c#/TestCore/UnitTest1.cs | 25 ++++++++++---- 10 files changed, 121 insertions(+), 48 deletions(-) create mode 100644 src/c#/GeneralUpdate.Core/Driver/DeleteDriverCommand.cs diff --git a/src/c#/GeneralUpdate.Client/Program.cs b/src/c#/GeneralUpdate.Client/Program.cs index 8278245..bcd1ce6 100644 --- a/src/c#/GeneralUpdate.Client/Program.cs +++ b/src/c#/GeneralUpdate.Client/Program.cs @@ -4,7 +4,7 @@ { static void Main(string[] args) { - Console.WriteLine("Hello, World!"); + Console.Read(); } } } diff --git a/src/c#/GeneralUpdate.Core/Driver/BackupDriverCommand.cs b/src/c#/GeneralUpdate.Core/Driver/BackupDriverCommand.cs index e09222b..7c89795 100644 --- a/src/c#/GeneralUpdate.Core/Driver/BackupDriverCommand.cs +++ b/src/c#/GeneralUpdate.Core/Driver/BackupDriverCommand.cs @@ -3,7 +3,6 @@ using System.Text; namespace GeneralUpdate.Core.Driver { - /// /// When the /export-driver command backs up a driver, it backs up the driver package along with all its dependencies, such as associated library files and other related files. /// @@ -11,22 +10,37 @@ namespace GeneralUpdate.Core.Driver { private DriverInformation _information; - public BackupDriverCommand(DriverInformation information) - { - _information = information; - } - + public BackupDriverCommand(DriverInformation information)=> _information = information; + public void Execute() { /* * Back up the specified list of drives. */ - foreach (var driverName in _information.DriverNames) + foreach (var driver in _information.Drivers) { - var command = new StringBuilder("/c dism /online /export-driver /destination:\"") - .Append(Path.Combine(_information.OutPutDirectory, driverName)) - .Append("\"") + //Export the backup according to the driver name. + var outPutDirectory = Path.Combine(_information.OutPutDirectory, Path.GetFileNameWithoutExtension(driver)); + + if (Directory.Exists(outPutDirectory)) + Directory.Delete(outPutDirectory, true); + + Directory.CreateDirectory(outPutDirectory); + + /* + * If no test driver files are available, you can run the following command to export all installed driver files. + * (1) dism /online /export-driver /destination:"D:\packet\cache\" + * (2) pnputil /export-driver * D:\packet\cache + * + * The following code example exports the specified driver to the specified directory. + * pnputil /export-driver oem14.inf D:\packet\cache + */ + var command = new StringBuilder("/c pnputil /export-driver ") + .Append(driver) + .Append(' ') + .Append(outPutDirectory) .ToString(); + CommandExecutor.ExecuteCommand(command); } } diff --git a/src/c#/GeneralUpdate.Core/Driver/CommandExecutor.cs b/src/c#/GeneralUpdate.Core/Driver/CommandExecutor.cs index 208f184..20055e5 100644 --- a/src/c#/GeneralUpdate.Core/Driver/CommandExecutor.cs +++ b/src/c#/GeneralUpdate.Core/Driver/CommandExecutor.cs @@ -11,26 +11,24 @@ namespace GeneralUpdate.Core.Driver public static void ExecuteCommand(string command) { /* + * *Problems may occur, including: Permission issues: PnPUtil requires administrator rights to run. If you try to run it without the proper permissions, the backup or restore may fail. Driver compatibility: Although the backed up drivers work properly at backup time, if the operating system is upgraded, the backed up drivers may no longer be compatible with the new operating system version. Hardware problems: If the hardware device fails or the hardware configuration changes, the backup driver may not work properly. -To minimize these risks, the following measures are recommended: + To minimize these risks, the following measures are recommended: Before doing anything, create a system restore point so that it can be restored to its previous state if something goes wrong. Update the driver regularly to ensure that the driver is compatible with the current operating system version. If possible, use pre-tested drivers that are proven to work. * */ - var processStartInfo = new ProcessStartInfo { WindowStyle = ProcessWindowStyle.Hidden, FileName = "cmd.exe", Arguments = command, - UseShellExecute = false, - RedirectStandardOutput = true, - CreateNoWindow = true, + UseShellExecute = true, Verb = "runas" }; @@ -40,7 +38,7 @@ If possible, use pre-tested drivers that are proven to work. process.WaitForExit(); if (process.ExitCode != 0) - throw new Exception("Operation failed: " + process.StandardOutput.ReadToEnd()); + throw new Exception($"Operation failed code: {process.ExitCode}"); } } } diff --git a/src/c#/GeneralUpdate.Core/Driver/DeleteDriverCommand.cs b/src/c#/GeneralUpdate.Core/Driver/DeleteDriverCommand.cs new file mode 100644 index 0000000..6fb4e1d --- /dev/null +++ b/src/c#/GeneralUpdate.Core/Driver/DeleteDriverCommand.cs @@ -0,0 +1,23 @@ +using System.Text; + +namespace GeneralUpdate.Core.Driver +{ + public class DeleteDriverCommand : IDriverCommand + { + private DriverInformation _information; + + public DeleteDriverCommand(DriverInformation information) => _information = information; + + public void Execute() + { + //Before installing the driver, delete the driver that has been installed on the local system. Otherwise, an exception may occur. + foreach (var driver in _information.Drivers) + { + var command = new StringBuilder("/c pnputil /delete-driver ") + .Append(driver) + .ToString(); + CommandExecutor.ExecuteCommand(command); + } + } + } +} diff --git a/src/c#/GeneralUpdate.Core/Driver/DriverInformation.cs b/src/c#/GeneralUpdate.Core/Driver/DriverInformation.cs index 95df5bf..be975aa 100644 --- a/src/c#/GeneralUpdate.Core/Driver/DriverInformation.cs +++ b/src/c#/GeneralUpdate.Core/Driver/DriverInformation.cs @@ -22,7 +22,7 @@ namespace GeneralUpdate.Core.Driver /// /// A collection of driver files to be backed up. /// - public List DriverNames { get; private set; } + public List Drivers { get; private set; } private DriverInformation(){} @@ -49,7 +49,7 @@ namespace GeneralUpdate.Core.Driver /// public Builder SetDriverNames(List driverNames) { - _information.DriverNames = driverNames; + _information.Drivers = driverNames; return this; } @@ -57,7 +57,7 @@ namespace GeneralUpdate.Core.Driver { if (string.IsNullOrWhiteSpace(_information.InstallDirectory) || string.IsNullOrWhiteSpace(_information.OutPutDirectory) || - !_information.DriverNames.Any()) + !_information.Drivers.Any()) { throw new InvalidOperationException("Cannot create DriverInformation, not all fields are set."); } diff --git a/src/c#/GeneralUpdate.Core/Driver/DriverProcessor.cs b/src/c#/GeneralUpdate.Core/Driver/DriverProcessor.cs index 8e927c8..9d02c28 100644 --- a/src/c#/GeneralUpdate.Core/Driver/DriverProcessor.cs +++ b/src/c#/GeneralUpdate.Core/Driver/DriverProcessor.cs @@ -19,11 +19,14 @@ namespace GeneralUpdate.Core.Driver /// public void ProcessCommands() { + /* + * This section describes the PnPUtil command. + * https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/pnputil-command-syntax + */ foreach (var command in _commands) { command.Execute(); } - _commands.Clear(); } } diff --git a/src/c#/GeneralUpdate.Core/Driver/InstallDriverCommand.cs b/src/c#/GeneralUpdate.Core/Driver/InstallDriverCommand.cs index 97ffe13..9e7a61f 100644 --- a/src/c#/GeneralUpdate.Core/Driver/InstallDriverCommand.cs +++ b/src/c#/GeneralUpdate.Core/Driver/InstallDriverCommand.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Text; namespace GeneralUpdate.Core.Driver @@ -7,24 +8,32 @@ namespace GeneralUpdate.Core.Driver { private DriverInformation _information; - public InstallDriverCommand(DriverInformation information) - { - _information = information; - } + public InstallDriverCommand(DriverInformation information)=> _information = information; public void Execute() { try { - //Install all drivers in the specified directory, and if the installation fails, restore all the drivers in the backup directory. - var command = new StringBuilder("/c pnputil /add-driver \"") - .Append(_information.InstallDirectory) - .Append("\"") - .ToString(); - CommandExecutor.ExecuteCommand(command); + foreach (var driver in _information.Drivers) + { + /* + * 1.It is best to ensure that the installed file is OEM INF, otherwise PnPUtil may indicate that non-OEM INF cannot perform the current operation. + * + * 2.Before installation, you need to delete the previously installed driver, otherwise PnPUtil will prompt 259 to exit the code. + * (On Windows, an ExitCode value of 259 (STILL_ACTIVE) means that the process is still running) + * If you do not remove the previous installation 259 prompt will give you a misleading impression of what is running. + */ + var path = Path.Combine(_information.InstallDirectory, Path.GetFileNameWithoutExtension(driver), driver); + var command = new StringBuilder("/c pnputil /add-driver ") + .Append(path) + .Append(" /install") + .ToString(); + CommandExecutor.ExecuteCommand(command); + } } catch (Exception ex) { + //restore all the drivers in the backup directory. new RestoreDriverCommand(_information).Execute(); throw new Exception($"Failed to execute install command for {_information.InstallDirectory}", ex); } diff --git a/src/c#/GeneralUpdate.Core/Driver/RestoreDriverCommand.cs b/src/c#/GeneralUpdate.Core/Driver/RestoreDriverCommand.cs index e24dbc5..b2c5d83 100644 --- a/src/c#/GeneralUpdate.Core/Driver/RestoreDriverCommand.cs +++ b/src/c#/GeneralUpdate.Core/Driver/RestoreDriverCommand.cs @@ -1,4 +1,6 @@ -using System.Text; +using System.IO; +using System; +using System.Text; namespace GeneralUpdate.Core.Driver { @@ -6,19 +8,26 @@ namespace GeneralUpdate.Core.Driver { private DriverInformation _information; - public RestoreDriverCommand(DriverInformation information) - { - _information = information; - } + public RestoreDriverCommand(DriverInformation information)=> _information = information; public void Execute() { - //Restore all drives in the backup directory. - var command = new StringBuilder("/c pnputil /add-driver \"") - .Append(_information.OutPutDirectory) - .Append("\"") - .ToString(); - CommandExecutor.ExecuteCommand(command); + try + { + foreach (var driver in _information.Drivers) + { + //Install all drivers in the specified directory, and if the installation fails, restore all the drivers in the backup directory. + var command = new StringBuilder("/c pnputil /add-driver ") + .Append(Path.Combine(_information.OutPutDirectory, Path.GetFileNameWithoutExtension(driver), driver)) + .Append(" /install") + .ToString(); + CommandExecutor.ExecuteCommand(command); + } + } + catch (Exception ex) + { + throw new Exception($"Failed to execute restore command for {_information.OutPutDirectory}", ex); + } } } } \ No newline at end of file diff --git a/src/c#/TestCore/TestCore.csproj b/src/c#/TestCore/TestCore.csproj index 51e6422..28ba577 100644 --- a/src/c#/TestCore/TestCore.csproj +++ b/src/c#/TestCore/TestCore.csproj @@ -16,4 +16,8 @@ + + + + diff --git a/src/c#/TestCore/UnitTest1.cs b/src/c#/TestCore/UnitTest1.cs index 671c5cb..d6663d9 100644 --- a/src/c#/TestCore/UnitTest1.cs +++ b/src/c#/TestCore/UnitTest1.cs @@ -1,16 +1,29 @@ +using GeneralUpdate.Core.Driver; + namespace TestCore { public class Tests { - [SetUp] - public void Setup() - { - } - [Test] public void Test1() { - Assert.Pass(); + string installDir = "D:\\packet\\patch"; + string outPutDir = "D:\\packet\\cache"; + string name = "netrasa.inf"; + + var information = new DriverInformation.Builder() + .SetInstallDirectory(installDir) + .SetOutPutDirectory(outPutDir) + .SetDriverNames(new List { name }) + .Build(); + + Assert.IsNotNull(information); + + var processor = new DriverProcessor(); + processor.AddCommand(new BackupDriverCommand(information)); + processor.AddCommand(new DeleteDriverCommand(information)); + processor.AddCommand(new InstallDriverCommand(information)); + processor.ProcessCommands(); } } } \ No newline at end of file -- Gitee