Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/c#/GeneralUpdate.Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
Console.Read();
}
}
}
34 changes: 24 additions & 10 deletions src/c#/GeneralUpdate.Core/Driver/BackupDriverCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,44 @@

namespace GeneralUpdate.Core.Driver
{

/// <summary>
/// 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.
/// </summary>
public class BackupDriverCommand : IDriverCommand
{
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);
}
}
Expand Down
10 changes: 4 additions & 6 deletions src/c#/GeneralUpdate.Core/Driver/CommandExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,24 @@ public class CommandExecutor
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"
};

Expand All @@ -40,7 +38,7 @@ Update the driver regularly to ensure that the driver is compatible with the cur
process.WaitForExit();

if (process.ExitCode != 0)
throw new Exception("Operation failed: " + process.StandardOutput.ReadToEnd());
throw new Exception($"Operation failed code: {process.ExitCode}");
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions src/c#/GeneralUpdate.Core/Driver/DeleteDriverCommand.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
}
6 changes: 3 additions & 3 deletions src/c#/GeneralUpdate.Core/Driver/DriverInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class DriverInformation
/// <summary>
/// A collection of driver files to be backed up.
/// </summary>
public List<string> DriverNames { get; private set; }
public List<string> Drivers { get; private set; }

private DriverInformation(){}

Expand All @@ -49,15 +49,15 @@ public Builder SetOutPutDirectory(string outPutDirectory)
/// <returns></returns>
public Builder SetDriverNames(List<string> driverNames)
{
_information.DriverNames = driverNames;
_information.Drivers = driverNames;
return this;
}

public DriverInformation Build()
{
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.");
}
Expand Down
5 changes: 4 additions & 1 deletion src/c#/GeneralUpdate.Core/Driver/DriverProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ public void AddCommand(IDriverCommand command)
/// </summary>
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();
}
}
Expand Down
29 changes: 19 additions & 10 deletions src/c#/GeneralUpdate.Core/Driver/InstallDriverCommand.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Text;

namespace GeneralUpdate.Core.Driver
Expand All @@ -7,24 +8,32 @@ public class InstallDriverCommand : IDriverCommand
{
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);
}
Expand Down
31 changes: 20 additions & 11 deletions src/c#/GeneralUpdate.Core/Driver/RestoreDriverCommand.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
using System.Text;
using System.IO;
using System;
using System.Text;

namespace GeneralUpdate.Core.Driver
{
public class RestoreDriverCommand : IDriverCommand
{
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);
}
}
}
}
4 changes: 4 additions & 0 deletions src/c#/TestCore/TestCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\GeneralUpdate.Core\GeneralUpdate.Core.csproj" />
</ItemGroup>

</Project>
25 changes: 19 additions & 6 deletions src/c#/TestCore/UnitTest1.cs
Original file line number Diff line number Diff line change
@@ -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<string> { 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();
}
}
}