From a29fb096dc5f4b41b34535cdf20571b60eca55ce Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 12 Jan 2026 04:01:01 +0000
Subject: [PATCH 1/3] Initial plan
From e85867495bdfd20e5e8a6efbf581383ab1fa6778 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 12 Jan 2026 04:04:38 +0000
Subject: [PATCH 2/3] Add UAC script command support to driver upgrade
functionality
Co-authored-by: JusterZhu <11714536+JusterZhu@users.noreply.github.com>
---
.../Driver/DisableUACCommand.cs | 13 ++++
.../Driver/DriverInformation.cs | 22 ++++++
.../Driver/RestoreUACCommand.cs | 13 ++++
.../Driver/ScriptCommand.cs | 68 +++++++++++++++++++
.../Pipeline/DriverMiddleware.cs | 26 ++++++-
5 files changed, 139 insertions(+), 3 deletions(-)
create mode 100644 src/c#/GeneralUpdate.Core/Driver/DisableUACCommand.cs
create mode 100644 src/c#/GeneralUpdate.Core/Driver/RestoreUACCommand.cs
create mode 100644 src/c#/GeneralUpdate.Core/Driver/ScriptCommand.cs
diff --git a/src/c#/GeneralUpdate.Core/Driver/DisableUACCommand.cs b/src/c#/GeneralUpdate.Core/Driver/DisableUACCommand.cs
new file mode 100644
index 00000000..7eb324d7
--- /dev/null
+++ b/src/c#/GeneralUpdate.Core/Driver/DisableUACCommand.cs
@@ -0,0 +1,13 @@
+namespace GeneralUpdate.Core.Driver
+{
+ ///
+ /// Command to disable User Account Control (UAC) via script execution.
+ /// The script content is not managed by this class; only the script entry point is provided.
+ ///
+ public class DisableUACCommand : ScriptCommand
+ {
+ public DisableUACCommand(string scriptPath) : base(scriptPath)
+ {
+ }
+ }
+}
diff --git a/src/c#/GeneralUpdate.Core/Driver/DriverInformation.cs b/src/c#/GeneralUpdate.Core/Driver/DriverInformation.cs
index e396e2a6..ea9424e8 100644
--- a/src/c#/GeneralUpdate.Core/Driver/DriverInformation.cs
+++ b/src/c#/GeneralUpdate.Core/Driver/DriverInformation.cs
@@ -18,6 +18,16 @@ public class DriverInformation
public string OutPutDirectory { get; private set; }
public string DriverDirectory { get; private set; }
+
+ ///
+ /// Path to the script that disables UAC.
+ ///
+ public string DisableUACScriptPath { get; private set; }
+
+ ///
+ /// Path to the script that restores UAC.
+ ///
+ public string RestoreUACScriptPath { get; private set; }
///
/// A collection of driver files to be backed up.
@@ -54,6 +64,18 @@ public Builder SetFieldMappings(Dictionary fieldMappings)
_information.FieldMappings = fieldMappings;
return this;
}
+
+ public Builder SetDisableUACScriptPath(string scriptPath)
+ {
+ _information.DisableUACScriptPath = scriptPath;
+ return this;
+ }
+
+ public Builder SetRestoreUACScriptPath(string scriptPath)
+ {
+ _information.RestoreUACScriptPath = scriptPath;
+ return this;
+ }
public DriverInformation Build()
{
diff --git a/src/c#/GeneralUpdate.Core/Driver/RestoreUACCommand.cs b/src/c#/GeneralUpdate.Core/Driver/RestoreUACCommand.cs
new file mode 100644
index 00000000..1b7e2a82
--- /dev/null
+++ b/src/c#/GeneralUpdate.Core/Driver/RestoreUACCommand.cs
@@ -0,0 +1,13 @@
+namespace GeneralUpdate.Core.Driver
+{
+ ///
+ /// Command to restore User Account Control (UAC) via script execution.
+ /// The script content is not managed by this class; only the script entry point is provided.
+ ///
+ public class RestoreUACCommand : ScriptCommand
+ {
+ public RestoreUACCommand(string scriptPath) : base(scriptPath)
+ {
+ }
+ }
+}
diff --git a/src/c#/GeneralUpdate.Core/Driver/ScriptCommand.cs b/src/c#/GeneralUpdate.Core/Driver/ScriptCommand.cs
new file mode 100644
index 00000000..b888fd82
--- /dev/null
+++ b/src/c#/GeneralUpdate.Core/Driver/ScriptCommand.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Diagnostics;
+using GeneralUpdate.Common.Shared;
+
+namespace GeneralUpdate.Core.Driver
+{
+ ///
+ /// Base class for executing script commands.
+ ///
+ public abstract class ScriptCommand : DriverCommand
+ {
+ protected string ScriptPath { get; }
+
+ protected ScriptCommand(string scriptPath)
+ {
+ if (string.IsNullOrWhiteSpace(scriptPath))
+ throw new ArgumentNullException(nameof(scriptPath), "Script path cannot be null or empty.");
+
+ ScriptPath = scriptPath;
+ }
+
+ public override void Execute()
+ {
+ ExecuteScript(ScriptPath);
+ }
+
+ ///
+ /// Execute a script file.
+ ///
+ /// Path to the script file to execute.
+ protected virtual void ExecuteScript(string scriptPath)
+ {
+ var processStartInfo = new ProcessStartInfo
+ {
+ WindowStyle = ProcessWindowStyle.Hidden,
+ FileName = scriptPath,
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ Verb = "runas"
+ };
+
+ var process = new Process();
+ try
+ {
+ process.StartInfo = processStartInfo;
+ process.Start();
+ process.WaitForExit();
+
+ var output = process.StandardOutput.ReadToEnd();
+ GeneralTracer.Info($"Script execution output: {output}");
+
+ var error = process.StandardError.ReadToEnd();
+ if (!string.IsNullOrEmpty(error))
+ {
+ GeneralTracer.Error($"Script execution error: {error}");
+ }
+
+ if (process.ExitCode != 0)
+ throw new ApplicationException($"Script execution failed with exit code: {process.ExitCode}");
+ }
+ finally
+ {
+ process.Dispose();
+ }
+ }
+ }
+}
diff --git a/src/c#/GeneralUpdate.Core/Pipeline/DriverMiddleware.cs b/src/c#/GeneralUpdate.Core/Pipeline/DriverMiddleware.cs
index c96ce6b0..5fb1d7b7 100644
--- a/src/c#/GeneralUpdate.Core/Pipeline/DriverMiddleware.cs
+++ b/src/c#/GeneralUpdate.Core/Pipeline/DriverMiddleware.cs
@@ -29,17 +29,37 @@ public Task InvokeAsync(PipelineContext context)
if (fieldMappings == null || fieldMappings.Count == 0)
return;
- var information = new DriverInformation.Builder()
+ var disableUACScriptPath = context.Get("DisableUACScriptPath");
+ var restoreUACScriptPath = context.Get("RestoreUACScriptPath");
+
+ var builder = new DriverInformation.Builder()
.SetDriverFileExtension(FileExtension)
.SetOutPutDirectory(outPutPath)
.SetDriverDirectory(patchPath)
- .SetFieldMappings(fieldMappings)
- .Build();
+ .SetFieldMappings(fieldMappings);
+
+ if (!string.IsNullOrWhiteSpace(disableUACScriptPath))
+ builder.SetDisableUACScriptPath(disableUACScriptPath);
+
+ if (!string.IsNullOrWhiteSpace(restoreUACScriptPath))
+ builder.SetRestoreUACScriptPath(restoreUACScriptPath);
+
+ var information = builder.Build();
var processor = new DriverProcessor();
+
+ // Disable UAC before driver operations if script path is provided
+ if (!string.IsNullOrWhiteSpace(information.DisableUACScriptPath))
+ processor.AddCommand(new DisableUACCommand(information.DisableUACScriptPath));
+
processor.AddCommand(new BackupDriverCommand(information));
processor.AddCommand(new DeleteDriverCommand(information));
processor.AddCommand(new InstallDriverCommand(information));
+
+ // Restore UAC after driver operations if script path is provided
+ if (!string.IsNullOrWhiteSpace(information.RestoreUACScriptPath))
+ processor.AddCommand(new RestoreUACCommand(information.RestoreUACScriptPath));
+
processor.ProcessCommands();
});
}
From b3981f9ade1c243d04f44876e543691fec4d677d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 12 Jan 2026 04:05:50 +0000
Subject: [PATCH 3/3] Fix UAC script execution and add security validations
Co-authored-by: JusterZhu <11714536+JusterZhu@users.noreply.github.com>
---
.../Driver/ScriptCommand.cs | 20 +++++++------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/src/c#/GeneralUpdate.Core/Driver/ScriptCommand.cs b/src/c#/GeneralUpdate.Core/Driver/ScriptCommand.cs
index b888fd82..7251ced7 100644
--- a/src/c#/GeneralUpdate.Core/Driver/ScriptCommand.cs
+++ b/src/c#/GeneralUpdate.Core/Driver/ScriptCommand.cs
@@ -30,13 +30,14 @@ public override void Execute()
/// Path to the script file to execute.
protected virtual void ExecuteScript(string scriptPath)
{
+ if (!System.IO.File.Exists(scriptPath))
+ throw new ApplicationException($"Script file not found: {scriptPath}");
+
var processStartInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = scriptPath,
- UseShellExecute = false,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
+ UseShellExecute = true,
Verb = "runas"
};
@@ -47,17 +48,10 @@ protected virtual void ExecuteScript(string scriptPath)
process.Start();
process.WaitForExit();
- var output = process.StandardOutput.ReadToEnd();
- GeneralTracer.Info($"Script execution output: {output}");
-
- var error = process.StandardError.ReadToEnd();
- if (!string.IsNullOrEmpty(error))
- {
- GeneralTracer.Error($"Script execution error: {error}");
- }
-
if (process.ExitCode != 0)
- throw new ApplicationException($"Script execution failed with exit code: {process.ExitCode}");
+ throw new ApplicationException($"Script execution failed for '{scriptPath}' with exit code: {process.ExitCode}");
+
+ GeneralTracer.Info($"Script executed successfully: {scriptPath}");
}
finally
{