diff --git a/src/Services/ClientGeneratorService.cs b/src/Services/ClientGeneratorService.cs
index e2e7ee6..62e5c21 100644
--- a/src/Services/ClientGeneratorService.cs
+++ b/src/Services/ClientGeneratorService.cs
@@ -7,36 +7,28 @@
namespace GeneralUpdate.Tools.Services;
///
-/// Generates client and upgrade console projects for simulation,
-/// each with a minimal .csproj + Program.cs using dotnet run --project.
+/// Generates single-file client.cs and upgrade.cs for simulation,
+/// using dotnet run with #r directives (exact NuGet version).
///
public class ClientGeneratorService
{
- private const string ClientCsproj = """
-
-
- Exe
- net10.0
- enable
- enable
-
-
-
-
-
-
-""";
+ private const string ClientTemplate = """
+#r "nuget:GeneralUpdate.ClientCore,10.4.6"
+#r "nuget:GeneralUpdate.Core,10.4.6"
+
+using GeneralUpdate.ClientCore;
+using GeneralUpdate.Common.Shared.Object;
+using GeneralUpdate.Common.Internal.Event;
- private const string ClientProgram = """
-var log = (string msg) => Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {msg}");
+var log = (string msg) => Console.WriteLine($"[{{DateTime.Now:HH:mm:ss}}] {{msg}}");
try
-{
+{{
log("Client started");
log("Install path: {0}");
- var config = new GeneralUpdate.Common.Shared.Object.Configinfo
- {
+ var config = new Configinfo
+ {{
ReportUrl = "{1}/Upgrade/Report",
UpdateUrl = "{1}/Upgrade/Verification",
AppName = "{2}",
@@ -46,114 +38,98 @@ public class ClientGeneratorService
UpgradeClientVersion = "{5}",
ProductId = "{6}",
AppSecretKey = "{7}",
- };
+ }};
- await new GeneralUpdate.ClientCore.GeneralClientBootstrap()
+ await new GeneralClientBootstrap()
.SetConfig(config)
.AddListenerMultiDownloadStatistics((_, e) =>
- {
- var v = e.Version as GeneralUpdate.Common.Shared.Object.VersionInfo;
- log($"Download: {v?.Version} {e.ProgressPercentage}% {e.Speed}/s");
- })
+ {{
+ var v = e.Version as VersionInfo;
+ log($"Download: {{v?.Version}} {{e.ProgressPercentage}}% {{e.Speed}}/s");
+ }})
.AddListenerMultiAllDownloadCompleted((_, e) =>
- {
- log(e.IsAllDownloadCompleted ? "All downloads completed" : $"Download failed: {e.FailedVersions.Count}");
- })
+ {{
+ log(e.IsAllDownloadCompleted ? "All downloads completed" : $"Download failed: {{e.FailedVersions.Count}}");
+ }})
.AddListenerException((_, e) =>
- {
- log($"ERROR: {e.Exception}");
- })
+ {{
+ log($"ERROR: {{e.Exception}}");
+ }})
.AddListenerUpdateInfo((_, e) =>
- {
- log($"Update info: Code={e.Info.Code}, Versions={e.Info.Body?.Count ?? 0}");
- })
+ {{
+ log($"Update info: Code={{e.Info.Code}}, Versions={{e.Info.Body?.Count ?? 0}}");
+ }})
.LaunchAsync();
log("Update process completed");
-}
+}}
catch (Exception ex)
-{
- log($"FATAL: {ex.Message}");
+{{
+ log($"FATAL: {{ex.Message}}");
Console.Error.WriteLine(ex);
Environment.Exit(1);
-}
+}}
""";
- private const string UpgradeCsproj = """
-
-
- Exe
- net10.0
- enable
- enable
-
-
-
-
-
-
-""";
+ private const string UpgradeTemplate = """
+#r "nuget:GeneralUpdate.Core,10.4.6"
+#r "nuget:GeneralUpdate.ClientCore,10.4.6"
- private const string UpgradeProgram = """
-var log = (string msg) => Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {msg}");
+using GeneralUpdate.Core;
+using GeneralUpdate.Common.Shared;
+using GeneralUpdate.Common.Internal.Event;
+
+var log = (string msg) => Console.WriteLine($"[{{DateTime.Now:HH:mm:ss}}] {{msg}}");
try
-{
+{{
log("Upgrade process started");
log("Working directory: " + Environment.CurrentDirectory);
- await new GeneralUpdate.Core.GeneralUpdateBootstrap()
+ await new GeneralUpdateBootstrap()
.AddListenerMultiDownloadStatistics((_, e) =>
- {
+ {{
var v = e.Version as GeneralUpdate.Common.Shared.Object.VersionInfo;
- log($"Download: {v?.Version} {e.ProgressPercentage}%");
- })
+ log($"Download: {{v?.Version}} {{e.ProgressPercentage}}%");
+ }})
.AddListenerMultiAllDownloadCompleted((_, e) =>
- {
+ {{
log(e.IsAllDownloadCompleted ? "Downloads done" : "Download failed");
- })
+ }})
.AddListenerException((_, e) =>
- {
- log($"ERROR: {e.Exception}");
- })
+ {{
+ log($"ERROR: {{e.Exception}}");
+ }})
.LaunchAsync();
log("Upgrade process finished successfully");
-}
+}}
catch (Exception ex)
-{
- log($"FATAL: {ex.Message}");
+{{
+ log($"FATAL: {{ex.Message}}");
Console.Error.WriteLine(ex);
Environment.Exit(1);
-}
+}}
""";
public async Task GenerateAsync(SimulateConfigModel config, string outputDir)
{
var serverUrl = $"http://127.0.0.1:{config.ServerPort}";
- // client/
- var clientDir = Path.Combine(outputDir, "client");
- Directory.CreateDirectory(clientDir);
- await File.WriteAllTextAsync(Path.Combine(clientDir, "client.csproj"), ClientCsproj, Encoding.UTF8);
- await File.WriteAllTextAsync(Path.Combine(clientDir, "Program.cs"),
- string.Format(ClientProgram,
+ await File.WriteAllTextAsync(Path.Combine(outputDir, "client.cs"),
+ string.Format(ClientTemplate,
EscapeForCSharp(config.AppDirectory),
serverUrl,
- "upgrade.exe", // AppName
- "client.exe", // MainAppName
+ "upgrade.cs",
+ "client.cs",
config.CurrentVersion,
- "1.0.0.0", // upgrade client version
+ "1.0.0.0",
config.ProductId,
config.AppSecretKey),
Encoding.UTF8);
- // upgrade/
- var upgradeDir = Path.Combine(outputDir, "upgrade");
- Directory.CreateDirectory(upgradeDir);
- await File.WriteAllTextAsync(Path.Combine(upgradeDir, "upgrade.csproj"), UpgradeCsproj, Encoding.UTF8);
- await File.WriteAllTextAsync(Path.Combine(upgradeDir, "Program.cs"),
- string.Format(UpgradeProgram,
+ await File.WriteAllTextAsync(Path.Combine(outputDir, "upgrade.cs"),
+ string.Format(UpgradeTemplate,
EscapeForCSharp(config.AppDirectory)),
Encoding.UTF8);
}
diff --git a/src/Services/SimulationService.cs b/src/Services/SimulationService.cs
index 2b70cb2..82017a1 100644
--- a/src/Services/SimulationService.cs
+++ b/src/Services/SimulationService.cs
@@ -57,14 +57,14 @@ public async Task RunAsync(
config.ServerPort = _server.Port;
// 4. Generate client/upgrade scripts
- Log("STEP 4: Generating client/upgrade projects", progress);
+ Log("STEP 4: Generating client.cs and upgrade.cs", progress);
await _generator.GenerateAsync(config, config.OutputDirectory);
- Log($" client/ → {config.OutputDirectory}/client", progress);
- Log($" upgrade/ → {config.OutputDirectory}/upgrade", progress);
+ Log($" client.cs → {config.OutputDirectory}", progress);
+ Log($" upgrade.cs → {config.OutputDirectory}", progress);
- // 5. Run client via dotnet run --project
- Log("STEP 5: Running client (dotnet run --project client)", progress);
- var clientResult = await RunDotNetProject(Path.Combine(config.OutputDirectory, "client"), ct);
+ // 5. Run client
+ Log("STEP 5: Running client (dotnet run client.cs)", progress);
+ var clientResult = await RunDotNetScript(config.OutputDirectory, "client.cs", ct);
Log(clientResult.Output, progress);
if (!clientResult.Success)
@@ -137,11 +137,11 @@ private void Validate(SimulateConfigModel config)
catch { throw new InvalidOperationException("dotnet CLI not found. Install .NET 10.0 SDK."); }
}
- private async Task<(bool Success, string Output)> RunDotNetProject(string projectDir, CancellationToken ct)
+ private async Task<(bool Success, string Output)> RunDotNetScript(string workDir, string script, CancellationToken ct)
{
- var psi = new ProcessStartInfo("dotnet", "run --project .")
+ var psi = new ProcessStartInfo("dotnet", $"run {script}")
{
- WorkingDirectory = projectDir,
+ WorkingDirectory = workDir,
RedirectStandardOutput = true,
RedirectStandardError = true,
StandardOutputEncoding = System.Text.Encoding.UTF8,