Skip to content

Commit 6851d38

Browse files
authored
feat: replace .csx generation with pre-compiled test_app .exe files (#60)
test_app/Client + test_app/Upgrade: net10.0 console apps with --arg support Client.exe: --server-url --install-path --current-version --app-secret --product-id --app-name Upgrade.exe: --install-path --current-version --target-version --app-secret --patch-name --hash CI: publish both test apps, copy into Tools output/test_app/ Simulate: copy .exe to output dir, run Client.exe with args instead of dotnet script
1 parent 4213569 commit 6851d38

6 files changed

Lines changed: 198 additions & 192 deletions

File tree

.github/workflows/publish.yml

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
with:
1515
dotnet-version: 10.0.x
1616

17-
- name: Publish
17+
- name: Publish Tools
1818
run: >
1919
dotnet publish src/GeneralUpdate.Tools.csproj
2020
-c Release -r win-x64
@@ -23,11 +23,31 @@ jobs:
2323
-p:IncludeAllContentForSelfExtract=true
2424
-o publish/win-x64
2525
26+
- name: Publish Client
27+
run: >
28+
dotnet publish test_app/Client/ClientSample.csproj
29+
-c Release -r win-x64
30+
-p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained
31+
-o publish/test_app/Client
32+
33+
- name: Publish Upgrade
34+
run: >
35+
dotnet publish test_app/Upgrade/UpgradeSample.csproj
36+
-c Release -r win-x64
37+
-p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained
38+
-o publish/test_app/Upgrade
39+
40+
- name: Copy test apps to Tools output
41+
run: |
42+
mkdir -p publish/win-x64/test_app
43+
cp publish/test_app/Client/ClientSample.exe publish/win-x64/test_app/Client.exe
44+
cp publish/test_app/Upgrade/UpgradeSample.exe publish/win-x64/test_app/Upgrade.exe
45+
2646
- name: Upload
2747
uses: actions/upload-artifact@v4
2848
with:
2949
name: win-x64
30-
path: publish/win-x64/GeneralUpdate.Tools.exe
50+
path: publish/win-x64/
3151

3252
build-linux:
3353
runs-on: ubuntu-latest
@@ -39,7 +59,7 @@ jobs:
3959
with:
4060
dotnet-version: 10.0.x
4161

42-
- name: Publish
62+
- name: Publish Tools
4363
run: >
4464
dotnet publish src/GeneralUpdate.Tools.csproj
4565
-c Release -r linux-x64
@@ -52,7 +72,7 @@ jobs:
5272
uses: actions/upload-artifact@v4
5373
with:
5474
name: linux-x64
55-
path: publish/linux-x64/GeneralUpdate.Tools
75+
path: publish/linux-x64/
5676

5777
release:
5878
needs: [build-windows, build-linux]
@@ -62,22 +82,19 @@ jobs:
6282
steps:
6383
- uses: actions/download-artifact@v4
6484

65-
- name: Show structure (debug)
66-
run: find . -type f
67-
6885
- name: Get timestamp
6986
id: ts
7087
run: echo "timestamp=$(date -u '+%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT
7188

72-
- name: Build
89+
- name: Package win
7390
working-directory: win-x64
74-
run: zip ../GeneralUpdate.Tools_${{ steps.ts.outputs.timestamp }}_win-x64.zip *
91+
run: zip ../GeneralUpdate.Tools_${{ steps.ts.outputs.timestamp }}_win-x64.zip -r *
7592

76-
- name: Build
93+
- name: Package linux
7794
working-directory: linux-x64
7895
run: |
7996
chmod +x *
80-
zip ../GeneralUpdate.Tools_${{ steps.ts.outputs.timestamp }}_linux-x64.zip *
97+
zip ../GeneralUpdate.Tools_${{ steps.ts.outputs.timestamp }}_linux-x64.zip -r *
8198
8299
- name: Create Release
83100
uses: softprops/action-gh-release@v2

src/Services/SimulationService.cs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ namespace GeneralUpdate.Tools.Services;
1212

1313
public class SimulationService
1414
{
15-
private readonly ClientGeneratorService _generator = new();
1615
private readonly LocalUpdateServer _server = new();
1716
private readonly StringBuilder _fullLog = new();
1817
private int _timeoutSeconds = 120;
@@ -35,11 +34,23 @@ public async Task<SimulationResult> RunAsync(
3534
Log($"STEP 2: Preparing {config.OutputDirectory}", progress);
3635
Directory.CreateDirectory(config.OutputDirectory);
3736

38-
// 3. Generate scripts
39-
Log("STEP 3: Generating client.csx and upgrade.csx", progress);
40-
await _generator.GenerateAsync(config, config.OutputDirectory);
41-
Log($" client.csx → {config.OutputDirectory}", progress);
42-
Log($" upgrade.csx → {config.OutputDirectory}", progress);
37+
// 3. Copy test app executables
38+
Log("STEP 3: Copying test executables", progress);
39+
var toolsDir = AppDomain.CurrentDomain.BaseDirectory;
40+
var clientSrc = Path.Combine(toolsDir, "test_app", "Client.exe");
41+
var upgradeSrc = Path.Combine(toolsDir, "test_app", "Upgrade.exe");
42+
43+
if (!File.Exists(clientSrc))
44+
throw new FileNotFoundException($"Client.exe not found at {clientSrc}. Ensure test_app is deployed.");
45+
if (!File.Exists(upgradeSrc))
46+
throw new FileNotFoundException($"Upgrade.exe not found at {upgradeSrc}. Ensure test_app is deployed.");
47+
48+
var clientDest = Path.Combine(config.OutputDirectory, "Client.exe");
49+
var upgradeDest = Path.Combine(config.OutputDirectory, "Upgrade.exe");
50+
File.Copy(clientSrc, clientDest, true);
51+
File.Copy(upgradeSrc, upgradeDest, true);
52+
Log($" Client.exe → {config.OutputDirectory}", progress);
53+
Log($" Upgrade.exe → {config.OutputDirectory}", progress);
4354

4455
// 4. Start server
4556
Log("STEP 4: Starting local server", progress);
@@ -58,8 +69,10 @@ public async Task<SimulationResult> RunAsync(
5869
config.ServerPort = _server.Port;
5970

6071
// 5. Run client
61-
Log("STEP 5: Running client (dotnet script client.csx)", progress);
62-
var clientResult = await RunDotNetScript(config.OutputDirectory, "client.csx", ct);
72+
Log("STEP 5: Running Client.exe", progress);
73+
var clientExe = Path.Combine(config.OutputDirectory, "Client.exe");
74+
var clientArgs = $"--server-url {_server.BaseUrl} --install-path \"{config.AppDirectory}\" --current-version {config.CurrentVersion} --app-secret {config.AppSecretKey} --product-id {config.ProductId} --app-name Upgrade.exe";
75+
var clientResult = await RunExe(clientExe, clientArgs, ct);
6376
Log(clientResult.Output, progress);
6477

6578
if (!clientResult.Success)
@@ -116,11 +129,10 @@ private void Validate(SimulateConfigModel config)
116129
catch { throw new InvalidOperationException("dotnet CLI not found"); }
117130
}
118131

119-
private async Task<(bool Success, string Output)> RunDotNetScript(string workDir, string script, CancellationToken ct)
132+
private async Task<(bool Success, string Output)> RunExe(string exePath, string arguments, CancellationToken ct)
120133
{
121-
var psi = new ProcessStartInfo("dotnet", $"script {script}")
134+
var psi = new ProcessStartInfo(exePath, arguments)
122135
{
123-
WorkingDirectory = workDir,
124136
RedirectStandardOutput = true, RedirectStandardError = true,
125137
StandardOutputEncoding = Encoding.UTF8, StandardErrorEncoding = Encoding.UTF8,
126138
UseShellExecute = false, CreateNoWindow = true
Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,11 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
2-
1+
<Project Sdk="Microsoft.NET.Sdk">
32
<PropertyGroup>
43
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
65
<ImplicitUsings>enable</ImplicitUsings>
76
<Nullable>enable</Nullable>
87
</PropertyGroup>
9-
10-
<ItemGroup>
11-
<None Remove="build.bat" />
12-
<None Remove="ClientSample.Desktop\**" />
13-
<None Remove="ClientSample\**" />
14-
</ItemGroup>
15-
168
<ItemGroup>
179
<PackageReference Include="GeneralUpdate.ClientCore" Version="10.4.6" />
1810
</ItemGroup>
19-
20-
<ItemGroup>
21-
<Compile Remove="ClientSample.Desktop\**" />
22-
<Compile Remove="ClientSample\**" />
23-
</ItemGroup>
24-
25-
<ItemGroup>
26-
<EmbeddedResource Remove="ClientSample.Desktop\**" />
27-
<EmbeddedResource Remove="ClientSample\**" />
28-
</ItemGroup>
29-
3011
</Project>

test_app/Client/Program.cs

Lines changed: 69 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,90 @@
1-
using System.Text;
1+
using System.Diagnostics;
22
using GeneralUpdate.ClientCore;
33
using GeneralUpdate.Common.Download;
44
using GeneralUpdate.Common.Internal;
55
using GeneralUpdate.Common.Internal.Bootstrap;
66
using GeneralUpdate.Common.Shared.Object;
77

8-
try
9-
{
10-
Console.WriteLine($"主程序初始化,{DateTime.Now}!");
11-
Console.WriteLine("当前运行目录:" + Thread.GetDomain().BaseDirectory);
12-
var configinfo = new Configinfo
13-
{
14-
//UpdateLogUrl = "https://www.baidu.com",
15-
ReportUrl = "http://127.0.0.1:5000/Upgrade/Report",
16-
UpdateUrl = "http://127.0.0.1:5000/Upgrade/Verification",
17-
AppName = "UpgradeSample.exe",
18-
MainAppName = "ClientSample.exe",
19-
InstallPath = Thread.GetDomain().BaseDirectory,
20-
//Bowl = "Generalupdate.CatBowl.exe",
21-
//当前客户端的版本号
22-
ClientVersion = "1.0.0.0",
23-
//当前升级端的版本号
24-
UpgradeClientVersion = "1.0.0.0",
25-
//产品id
26-
ProductId = "2d974e2a-31e6-4887-9bb1-b4689e98c77a",
27-
//应用密钥
28-
AppSecretKey = "dfeb5833-975e-4afb-88f1-6278ee9aeff6",
29-
//BlackFiles = new List<string> { "123.exe" },
30-
//BlackFormats = new List<string> { "123.dll" },
31-
//SkipDirectorys = new List<string> { "logs" },
32-
//Scheme = "Bearer",
33-
//Token = "..."
34-
};
35-
_ = await new GeneralClientBootstrap()
36-
//单个或多个更新包下载速度、剩余下载事件、当前下载版本信息通知事件
37-
.AddListenerMultiDownloadStatistics(OnMultiDownloadStatistics)
38-
//单个或多个更新包下载完成
39-
.AddListenerMultiDownloadCompleted(OnMultiDownloadCompleted)
40-
//完成所有的下载任务通知
41-
.AddListenerMultiAllDownloadCompleted(OnMultiAllDownloadCompleted)
42-
//下载过程出现的异常通知
43-
.AddListenerMultiDownloadError(OnMultiDownloadError)
44-
//整个更新过程出现的任何问题都会通过这个事件通知
45-
.AddListenerException(OnException)
46-
//服务端返回更新信息后的通知(可用于显示更新日志、版本信息等)
47-
.AddListenerUpdateInfo(OnUpdateInfo)
48-
//更新预检回调:返回 true 跳过本次更新,返回 false 继续自动更新
49-
//(强制更新版本会忽略此回调)
50-
.AddListenerUpdatePrecheck(OnUpdatePrecheck)
51-
.SetConfig(configinfo)
52-
.Option(UpdateOption.DownloadTimeOut, 60)
53-
.Option(UpdateOption.Encoding, Encoding.Default)
54-
.LaunchAsync();
55-
Console.WriteLine($"主程序已启动,{DateTime.Now}!");
56-
await Task.Delay(2000);
57-
}
58-
catch (Exception e)
59-
{
60-
Console.WriteLine(e.Message + "\n" + e.StackTrace);
61-
}
8+
// Parse command-line arguments
9+
var cliArgs = ParseArgs(args);
6210

63-
void OnMultiDownloadError(object arg1, MultiDownloadErrorEventArgs arg2)
64-
{
65-
var version = arg2.Version as VersionInfo;
66-
Console.WriteLine($"{version?.Version} {arg2.Exception}");
67-
}
11+
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Client started");
12+
Console.WriteLine($"Install path: {cliArgs.InstallPath}");
6813

69-
void OnMultiAllDownloadCompleted(object arg1, MultiAllDownloadCompletedEventArgs arg2)
14+
var configinfo = new Configinfo
7015
{
71-
Console.WriteLine(arg2.IsAllDownloadCompleted ? "所有的下载任务已完成!" : $"下载任务已失败!{arg2.FailedVersions.Count}");
72-
}
16+
ReportUrl = $"{cliArgs.ServerUrl}/Upgrade/Report",
17+
UpdateUrl = $"{cliArgs.ServerUrl}/Upgrade/Verification",
18+
AppName = cliArgs.AppName,
19+
MainAppName = AppDomain.CurrentDomain.FriendlyName,
20+
InstallPath = cliArgs.InstallPath,
21+
ClientVersion = cliArgs.CurrentVersion,
22+
UpgradeClientVersion = "1.0.0.0",
23+
ProductId = cliArgs.ProductId,
24+
AppSecretKey = cliArgs.AppSecret,
25+
};
7326

74-
void OnMultiDownloadCompleted(object arg1, MultiDownloadCompletedEventArgs arg2)
27+
try
7528
{
76-
var version = arg2.Version as VersionInfo;
77-
Console.WriteLine(arg2.IsComplated ? $"当前下载版本:{version?.Version}, 下载完成!" : $"当前下载版本:{version?.Version}, 下载失败!");
78-
}
29+
await new GeneralClientBootstrap()
30+
.AddListenerMultiDownloadStatistics((_, e) =>
31+
{
32+
var v = e.Version as VersionInfo;
33+
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Download: {v?.Version} {e.ProgressPercentage}%");
34+
})
35+
.AddListenerMultiAllDownloadCompleted((_, e) =>
36+
{
37+
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] All downloads: {(e.IsAllDownloadCompleted ? "completed" : $"failed ({e.FailedVersions.Count})")}");
38+
})
39+
.AddListenerMultiDownloadCompleted((_, e) =>
40+
{
41+
var v = e.Version as VersionInfo;
42+
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Download {v?.Version}: {(e.IsComplated ? "done" : "failed")}");
43+
})
44+
.AddListenerException((_, e) =>
45+
{
46+
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] ERROR: {e.Exception}");
47+
})
48+
.AddListenerUpdateInfo((_, e) =>
49+
{
50+
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Update info: Code={e.Info.Code}, Versions={e.Info.Body?.Count ?? 0}");
51+
})
52+
.SetConfig(configinfo)
53+
.Option(UpdateOption.DownloadTimeOut, 60)
54+
.LaunchAsync();
7955

80-
void OnMultiDownloadStatistics(object arg1, MultiDownloadStatisticsEventArgs arg2)
81-
{
82-
var version = arg2.Version as VersionInfo;
83-
Console.WriteLine(
84-
$"当前下载版本:{version?.Version},下载速度:{arg2.Speed},剩余下载时间:{arg2.Remaining},已下载大小:{arg2.BytesReceived},总大小:{arg2.TotalBytesToReceive}, 进度百分比:{arg2.ProgressPercentage}%");
56+
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Client completed successfully");
8557
}
86-
87-
void OnException(object arg1, ExceptionEventArgs arg2)
58+
catch (Exception ex)
8859
{
89-
Console.WriteLine($"{arg2.Exception}");
60+
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] FATAL: {ex.Message}");
61+
Environment.Exit(1);
9062
}
9163

92-
void OnUpdateInfo(object arg1, UpdateInfoEventArgs arg2)
64+
static ClientArgs ParseArgs(string[] argv)
9365
{
94-
// arg2.Info 包含服务端返回的完整版本信息(VersionRespDTO)
95-
Console.WriteLine($"服务端返回更新信息:Code={arg2.Info.Code}, 版本数量={arg2.Info.Body?.Count ?? 0}");
66+
var a = new ClientArgs();
67+
for (int i = 0; i < argv.Length; i++)
68+
{
69+
switch (argv[i])
70+
{
71+
case "--server-url" when i + 1 < argv.Length: a.ServerUrl = argv[++i]; break;
72+
case "--install-path" when i + 1 < argv.Length: a.InstallPath = argv[++i]; break;
73+
case "--current-version" when i + 1 < argv.Length: a.CurrentVersion = argv[++i]; break;
74+
case "--app-secret" when i + 1 < argv.Length: a.AppSecret = argv[++i]; break;
75+
case "--product-id" when i + 1 < argv.Length: a.ProductId = argv[++i]; break;
76+
case "--app-name" when i + 1 < argv.Length: a.AppName = argv[++i]; break;
77+
}
78+
}
79+
return a;
9680
}
9781

98-
bool OnUpdatePrecheck(UpdateInfoEventArgs arg)
82+
class ClientArgs
9983
{
100-
// 返回 true:跳过本次更新;返回 false:继续执行自动更新
101-
// 可在此处添加自定义判断逻辑,例如检查磁盘空间、询问用户是否立即更新等
102-
Console.WriteLine($"更新预检:发现 {arg.Info.Body?.Count ?? 0} 个可用版本,继续更新...");
103-
return false; // false = 继续更新
84+
public string ServerUrl { get; set; } = "http://127.0.0.1:5000";
85+
public string InstallPath { get; set; } = AppDomain.CurrentDomain.BaseDirectory;
86+
public string CurrentVersion { get; set; } = "1.0.0.0";
87+
public string AppSecret { get; set; } = "dfeb5833-975e-4afb-88f1-6278ee9aeff6";
88+
public string ProductId { get; set; } = "2d974e2a-31e6-4887-9bb1-b4689e98c77a";
89+
public string AppName { get; set; } = "Upgrade.exe";
10490
}

0 commit comments

Comments
 (0)