Skip to content

Commit 90bfc0e

Browse files
authored
fix: generate .csproj projects instead of #r scripts (#42)
- Replace single-file .cs with client/Program.cs + client/client.csproj - Replace single-file .cs with upgrade/Program.cs + upgrade/upgrade.csproj - Use dotnet run --project . instead of dotnet run script.cs - #r directives are not supported in .cs files by .NET 10 - .csproj approach is more reliable, no NuGet version issues
1 parent d7754f5 commit 90bfc0e

2 files changed

Lines changed: 100 additions & 84 deletions

File tree

src/Services/ClientGeneratorService.cs

Lines changed: 91 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,36 @@
77
namespace GeneralUpdate.Tools.Services;
88

99
/// <summary>
10-
/// Generates single-file client.cs and upgrade.cs for simulation,
11-
/// using dotnet-run (#r nuget:...) without project files.
10+
/// Generates client and upgrade console projects for simulation,
11+
/// each with a minimal .csproj + Program.cs using dotnet run --project.
1212
/// </summary>
1313
public class ClientGeneratorService
1414
{
15-
private const string ClientTemplate = """
16-
#r "nuget: GeneralUpdate.ClientCore"
17-
#r "nuget: GeneralUpdate.Core"
18-
19-
using GeneralUpdate.ClientCore;
20-
using GeneralUpdate.Common.Shared.Object;
21-
using GeneralUpdate.Common.Internal.Event;
15+
private const string ClientCsproj = """
16+
<Project Sdk="Microsoft.NET.Sdk">
17+
<PropertyGroup>
18+
<OutputType>Exe</OutputType>
19+
<TargetFramework>net10.0</TargetFramework>
20+
<Nullable>enable</Nullable>
21+
<ImplicitUsings>enable</ImplicitUsings>
22+
</PropertyGroup>
23+
<ItemGroup>
24+
<PackageReference Include="GeneralUpdate.ClientCore" Version="10.*" />
25+
<PackageReference Include="GeneralUpdate.Core" Version="10.*" />
26+
</ItemGroup>
27+
</Project>
28+
""";
2229

23-
var log = (string msg) => Console.WriteLine($"[{{DateTime.Now:HH:mm:ss}}] {{msg}}");
30+
private const string ClientProgram = """
31+
var log = (string msg) => Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {msg}");
2432
2533
try
26-
{{
34+
{
2735
log("Client started");
2836
log("Install path: {0}");
2937
30-
var config = new Configinfo
31-
{{
38+
var config = new GeneralUpdate.Common.Shared.Object.Configinfo
39+
{
3240
ReportUrl = "{1}/Upgrade/Report",
3341
UpdateUrl = "{1}/Upgrade/Verification",
3442
AppName = "{2}",
@@ -38,107 +46,115 @@ public class ClientGeneratorService
3846
UpgradeClientVersion = "{5}",
3947
ProductId = "{6}",
4048
AppSecretKey = "{7}",
41-
}};
49+
};
4250
43-
await new GeneralClientBootstrap()
51+
await new GeneralUpdate.ClientCore.GeneralClientBootstrap()
4452
.SetConfig(config)
4553
.AddListenerMultiDownloadStatistics((_, e) =>
46-
{{
47-
var v = e.Version as VersionInfo;
48-
log($"Download: {{v?.Version}} {{e.ProgressPercentage}}% {{e.Speed}}/s");
49-
}})
54+
{
55+
var v = e.Version as GeneralUpdate.Common.Shared.Object.VersionInfo;
56+
log($"Download: {v?.Version} {e.ProgressPercentage}% {e.Speed}/s");
57+
})
5058
.AddListenerMultiAllDownloadCompleted((_, e) =>
51-
{{
52-
log(e.IsAllDownloadCompleted ? "All downloads completed" : $"Download failed: {{e.FailedVersions.Count}}");
53-
}})
59+
{
60+
log(e.IsAllDownloadCompleted ? "All downloads completed" : $"Download failed: {e.FailedVersions.Count}");
61+
})
5462
.AddListenerException((_, e) =>
55-
{{
56-
log($"ERROR: {{e.Exception}}");
57-
}})
63+
{
64+
log($"ERROR: {e.Exception}");
65+
})
5866
.AddListenerUpdateInfo((_, e) =>
59-
{{
60-
log($"Update info: Code={{e.Info.Code}}, Versions={{e.Info.Body?.Count ?? 0}}");
61-
}})
67+
{
68+
log($"Update info: Code={e.Info.Code}, Versions={e.Info.Body?.Count ?? 0}");
69+
})
6270
.LaunchAsync();
6371
6472
log("Update process completed");
65-
}}
73+
}
6674
catch (Exception ex)
67-
{{
68-
log($"FATAL: {{ex.Message}}");
75+
{
76+
log($"FATAL: {ex.Message}");
6977
Console.Error.WriteLine(ex);
7078
Environment.Exit(1);
71-
}}
79+
}
7280
""";
7381

74-
private const string UpgradeTemplate = """
75-
#r "nuget: GeneralUpdate.Core"
76-
#r "nuget: GeneralUpdate.ClientCore"
77-
78-
using GeneralUpdate.Core;
79-
using GeneralUpdate.Common.Shared;
80-
using GeneralUpdate.Common.Internal.Event;
82+
private const string UpgradeCsproj = """
83+
<Project Sdk="Microsoft.NET.Sdk">
84+
<PropertyGroup>
85+
<OutputType>Exe</OutputType>
86+
<TargetFramework>net10.0</TargetFramework>
87+
<Nullable>enable</Nullable>
88+
<ImplicitUsings>enable</ImplicitUsings>
89+
</PropertyGroup>
90+
<ItemGroup>
91+
<PackageReference Include="GeneralUpdate.Core" Version="10.*" />
92+
<PackageReference Include="GeneralUpdate.ClientCore" Version="10.*" />
93+
</ItemGroup>
94+
</Project>
95+
""";
8196

82-
var log = (string msg) => Console.WriteLine($"[{{DateTime.Now:HH:mm:ss}}] {{msg}}");
97+
private const string UpgradeProgram = """
98+
var log = (string msg) => Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {msg}");
8399
84100
try
85-
{{
101+
{
86102
log("Upgrade process started");
87103
log("Working directory: " + Environment.CurrentDirectory);
88104
89-
await new GeneralUpdateBootstrap()
105+
await new GeneralUpdate.Core.GeneralUpdateBootstrap()
90106
.AddListenerMultiDownloadStatistics((_, e) =>
91-
{{
107+
{
92108
var v = e.Version as GeneralUpdate.Common.Shared.Object.VersionInfo;
93-
log($"Download: {{v?.Version}} {{e.ProgressPercentage}}%");
94-
}})
109+
log($"Download: {v?.Version} {e.ProgressPercentage}%");
110+
})
95111
.AddListenerMultiAllDownloadCompleted((_, e) =>
96-
{{
112+
{
97113
log(e.IsAllDownloadCompleted ? "Downloads done" : "Download failed");
98-
}})
114+
})
99115
.AddListenerException((_, e) =>
100-
{{
101-
log($"ERROR: {{e.Exception}}");
102-
}})
116+
{
117+
log($"ERROR: {e.Exception}");
118+
})
103119
.LaunchAsync();
104120
105121
log("Upgrade process finished successfully");
106-
}}
122+
}
107123
catch (Exception ex)
108-
{{
109-
log($"FATAL: {{ex.Message}}");
124+
{
125+
log($"FATAL: {ex.Message}");
110126
Console.Error.WriteLine(ex);
111127
Environment.Exit(1);
112-
}}
128+
}
113129
""";
114130

115131
public async Task GenerateAsync(SimulateConfigModel config, string outputDir)
116132
{
117133
var serverUrl = $"http://127.0.0.1:{config.ServerPort}";
118134

119-
// client.cs
120-
var clientCode = string.Format(ClientTemplate,
121-
EscapeForCSharp(config.AppDirectory),
122-
serverUrl,
123-
"upgrade.cs", // AppName - the upgrade process
124-
"client.cs", // MainAppName
125-
config.CurrentVersion,
126-
"1.0.0.0", // upgrade client version
127-
config.ProductId,
128-
config.AppSecretKey);
129-
130-
await File.WriteAllTextAsync(
131-
Path.Combine(outputDir, "client.cs"),
132-
clientCode,
135+
// client/
136+
var clientDir = Path.Combine(outputDir, "client");
137+
Directory.CreateDirectory(clientDir);
138+
await File.WriteAllTextAsync(Path.Combine(clientDir, "client.csproj"), ClientCsproj, Encoding.UTF8);
139+
await File.WriteAllTextAsync(Path.Combine(clientDir, "Program.cs"),
140+
string.Format(ClientProgram,
141+
EscapeForCSharp(config.AppDirectory),
142+
serverUrl,
143+
"upgrade.exe", // AppName
144+
"client.exe", // MainAppName
145+
config.CurrentVersion,
146+
"1.0.0.0", // upgrade client version
147+
config.ProductId,
148+
config.AppSecretKey),
133149
Encoding.UTF8);
134150

135-
// upgrade.cs
136-
var upgradeCode = string.Format(UpgradeTemplate,
137-
EscapeForCSharp(config.AppDirectory));
138-
139-
await File.WriteAllTextAsync(
140-
Path.Combine(outputDir, "upgrade.cs"),
141-
upgradeCode,
151+
// upgrade/
152+
var upgradeDir = Path.Combine(outputDir, "upgrade");
153+
Directory.CreateDirectory(upgradeDir);
154+
await File.WriteAllTextAsync(Path.Combine(upgradeDir, "upgrade.csproj"), UpgradeCsproj, Encoding.UTF8);
155+
await File.WriteAllTextAsync(Path.Combine(upgradeDir, "Program.cs"),
156+
string.Format(UpgradeProgram,
157+
EscapeForCSharp(config.AppDirectory)),
142158
Encoding.UTF8);
143159
}
144160

src/Services/SimulationService.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ public async Task<SimulationResult> RunAsync(
5757
config.ServerPort = _server.Port;
5858

5959
// 4. Generate client/upgrade scripts
60-
Log("STEP 4: Generating client.cs and upgrade.cs", progress);
60+
Log("STEP 4: Generating client/upgrade projects", progress);
6161
await _generator.GenerateAsync(config, config.OutputDirectory);
62-
Log($" client.cs{config.OutputDirectory}", progress);
63-
Log($" upgrade.cs{config.OutputDirectory}", progress);
62+
Log($" client/{config.OutputDirectory}/client", progress);
63+
Log($" upgrade/{config.OutputDirectory}/upgrade", progress);
6464

65-
// 5. Run client
66-
Log("STEP 5: Running client (dotnet run client.cs)", progress);
67-
var clientResult = await RunDotNetScript(config.OutputDirectory, "client.cs", ct);
65+
// 5. Run client via dotnet run --project
66+
Log("STEP 5: Running client (dotnet run --project client)", progress);
67+
var clientResult = await RunDotNetProject(Path.Combine(config.OutputDirectory, "client"), ct);
6868
Log(clientResult.Output, progress);
6969

7070
if (!clientResult.Success)
@@ -137,11 +137,11 @@ private void Validate(SimulateConfigModel config)
137137
catch { throw new InvalidOperationException("dotnet CLI not found. Install .NET 10.0 SDK."); }
138138
}
139139

140-
private async Task<(bool Success, string Output)> RunDotNetScript(string workDir, string script, CancellationToken ct)
140+
private async Task<(bool Success, string Output)> RunDotNetProject(string projectDir, CancellationToken ct)
141141
{
142-
var psi = new ProcessStartInfo("dotnet", $"run {script}")
142+
var psi = new ProcessStartInfo("dotnet", "run --project .")
143143
{
144-
WorkingDirectory = workDir,
144+
WorkingDirectory = projectDir,
145145
RedirectStandardOutput = true,
146146
RedirectStandardError = true,
147147
StandardOutputEncoding = System.Text.Encoding.UTF8,

0 commit comments

Comments
 (0)