diff --git a/src/c#/GeneralUpdate.Core/Bootstrap/GeneralUpdateBootstrap.cs b/src/c#/GeneralUpdate.Core/Bootstrap/GeneralUpdateBootstrap.cs index d391ed2a..ab6ddcda 100644 --- a/src/c#/GeneralUpdate.Core/Bootstrap/GeneralUpdateBootstrap.cs +++ b/src/c#/GeneralUpdate.Core/Bootstrap/GeneralUpdateBootstrap.cs @@ -180,6 +180,37 @@ public GeneralUpdateBootstrap SetCustomSkipOption(Func? func) return this; } + /// + /// Load configuration from a local JSON file. + /// + /// + /// Config file path. + /// If just a filename (no directory separator), resolves relative to the current directory. + /// Relative or absolute paths are used as-is. + /// + public GeneralUpdateBootstrap SetConfig(string filePath) + { + if (string.IsNullOrWhiteSpace(filePath)) + throw new ArgumentNullException(nameof(filePath)); + + // Resolve filename-only paths to current directory + var hasPathChar = filePath.Contains(Path.DirectorySeparatorChar) + || filePath.Contains(Path.AltDirectorySeparatorChar); + var fullPath = hasPathChar + ? Path.GetFullPath(filePath) + : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, filePath); + + if (!File.Exists(fullPath)) + throw new FileNotFoundException($"Config file not found: {fullPath}"); + + var json = File.ReadAllText(fullPath); + var config = JsonSerializer.Deserialize(json, JsonContext.HttpParameterJsonContext.Default.Configinfo); + if (config == null) + throw new InvalidOperationException($"Failed to parse config file: {fullPath}"); + + return SetConfig(config); + } + public GeneralUpdateBootstrap AddListenerUpdatePrecheck(Func func) { _updatePrecheck = func ?? throw new ArgumentNullException(nameof(func)); diff --git a/src/c#/GeneralUpdate.Core/JsonContext/HttpParameterJsonContext.cs b/src/c#/GeneralUpdate.Core/JsonContext/HttpParameterJsonContext.cs index 4e8083e7..1e89de87 100644 --- a/src/c#/GeneralUpdate.Core/JsonContext/HttpParameterJsonContext.cs +++ b/src/c#/GeneralUpdate.Core/JsonContext/HttpParameterJsonContext.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Text.Json.Serialization; +using GeneralUpdate.Core.Configuration; using GeneralUpdate.Core.Download.Abstractions; namespace GeneralUpdate.Core.JsonContext; @@ -12,4 +13,5 @@ namespace GeneralUpdate.Core.JsonContext; [JsonSerializable(typeof(Dictionary))] [JsonSerializable(typeof(PacketDTO))] [JsonSerializable(typeof(List))] +[JsonSerializable(typeof(Configinfo))] public partial class HttpParameterJsonContext: JsonSerializerContext; \ No newline at end of file diff --git a/tests/CoreTest/Integration/OssIntegrationTests.cs b/tests/CoreTest/Integration/OssIntegrationTests.cs index 26626f51..92e2560b 100644 --- a/tests/CoreTest/Integration/OssIntegrationTests.cs +++ b/tests/CoreTest/Integration/OssIntegrationTests.cs @@ -72,8 +72,9 @@ await Assert.ThrowsAsync(() => } [Fact] - public async Task OSSUpdateStrategy_RequiresConfig() + public async Task OSSUpdateStrategy_WithoutConfig_ReturnsWithoutError() { + // OSS client without UpdateUrl or local version config: no exception, just returns var strategy = new OSSUpdateStrategy(); var config = new GlobalConfigInfo { @@ -83,8 +84,8 @@ public async Task OSSUpdateStrategy_RequiresConfig() }; strategy.Create(config); - await Assert.ThrowsAsync(() => - strategy.ExecuteAsync()); + var ex = await Record.ExceptionAsync(() => strategy.ExecuteAsync()); + Assert.Null(ex); } [Fact]