增强应用程序异常处理机制,新增未处理异常日志记录功能,确保在启动和运行期间捕获并记录异常信息。同时,重构配置文件加载逻辑,支持用户目录覆盖默认配置,优化 SQLite 数据库连接字符串处理,确保在不同环境下的兼容性和稳定性。
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.IO;
|
||||
using YY.Admin.Core.Util;
|
||||
|
||||
namespace YY.Admin.Helper
|
||||
{
|
||||
@@ -11,6 +12,37 @@ namespace YY.Admin.Helper
|
||||
{
|
||||
private const string DefaultWebSocketPath = "/websocket/scada-sync";
|
||||
|
||||
/// <summary>
|
||||
/// 安装目录随包发布的默认配置(只读)。
|
||||
/// </summary>
|
||||
public static string GetBundledAppSettingsPath()
|
||||
{
|
||||
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configuration", "appsettings.json");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户覆盖配置(可写),仅覆盖 JeecgIntegration 节点时使用。
|
||||
/// </summary>
|
||||
public static string GetUserAppSettingsPath()
|
||||
{
|
||||
var dir = AppWritablePaths.EnsureDirectoryExists(AppWritablePaths.ConfigurationDirectory);
|
||||
return Path.Combine(dir, "appsettings.json");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兼容旧调用:优先返回用于读取的实际路径(存在用户覆盖则用用户文件)。
|
||||
/// </summary>
|
||||
public static string GetConfigPath()
|
||||
{
|
||||
var user = GetUserAppSettingsPath();
|
||||
if (File.Exists(user))
|
||||
{
|
||||
return user;
|
||||
}
|
||||
|
||||
return GetBundledAppSettingsPath();
|
||||
}
|
||||
|
||||
public class ServerSettingsModel
|
||||
{
|
||||
public string Ip { get; set; } = "127.0.0.1";
|
||||
@@ -25,22 +57,35 @@ namespace YY.Admin.Helper
|
||||
public bool DisconnectConnection { get; set; } = false;
|
||||
}
|
||||
|
||||
public static string GetConfigPath()
|
||||
private static JObject LoadMergedRoot()
|
||||
{
|
||||
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configuration", "appsettings.json");
|
||||
var bundledPath = GetBundledAppSettingsPath();
|
||||
if (!File.Exists(bundledPath))
|
||||
{
|
||||
throw new FileNotFoundException("未找到安装目录默认配置文件 appsettings.json", bundledPath);
|
||||
}
|
||||
|
||||
var root = JObject.Parse(File.ReadAllText(bundledPath));
|
||||
var userPath = GetUserAppSettingsPath();
|
||||
if (!File.Exists(userPath))
|
||||
{
|
||||
return root;
|
||||
}
|
||||
|
||||
var userRoot = JObject.Parse(File.ReadAllText(userPath));
|
||||
var userJeecg = userRoot["JeecgIntegration"] as JObject;
|
||||
if (userJeecg != null)
|
||||
{
|
||||
root["JeecgIntegration"] = userJeecg;
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public static ServerSettingsModel Load()
|
||||
{
|
||||
var model = new ServerSettingsModel();
|
||||
var path = GetConfigPath();
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
||||
var content = File.ReadAllText(path);
|
||||
var root = JObject.Parse(content);
|
||||
var root = LoadMergedRoot();
|
||||
var jeecg = root["JeecgIntegration"] as JObject;
|
||||
if (jeecg == null)
|
||||
{
|
||||
@@ -64,14 +109,7 @@ namespace YY.Admin.Helper
|
||||
|
||||
public static void Save(ServerSettingsModel model)
|
||||
{
|
||||
var path = GetConfigPath();
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
throw new FileNotFoundException("未找到配置文件 appsettings.json", path);
|
||||
}
|
||||
|
||||
var content = File.ReadAllText(path);
|
||||
var root = JObject.Parse(content);
|
||||
var root = LoadMergedRoot();
|
||||
var jeecg = root["JeecgIntegration"] as JObject;
|
||||
if (jeecg == null)
|
||||
{
|
||||
@@ -95,7 +133,9 @@ namespace YY.Admin.Helper
|
||||
jeecg["WebSocketPath"] = webSocketPath;
|
||||
jeecg["DisconnectConnection"] = model.DisconnectConnection;
|
||||
|
||||
File.WriteAllText(path, root.ToString(Formatting.Indented));
|
||||
var userPath = GetUserAppSettingsPath();
|
||||
var outRoot = new JObject { ["JeecgIntegration"] = jeecg };
|
||||
File.WriteAllText(userPath, outRoot.ToString(Formatting.Indented));
|
||||
}
|
||||
|
||||
public static string BuildDefaultWebSocketUrl(string baseScheme, string ip, int port, string basePath, string webSocketPath = DefaultWebSocketPath)
|
||||
@@ -106,6 +146,7 @@ namespace YY.Admin.Helper
|
||||
{
|
||||
safeBasePath = "/" + safeBasePath;
|
||||
}
|
||||
|
||||
var safeWsPath = NormalizeWebSocketPath(webSocketPath);
|
||||
return $"{safeScheme}://{ip}:{port}{safeBasePath}{safeWsPath}";
|
||||
}
|
||||
@@ -117,6 +158,7 @@ namespace YY.Admin.Helper
|
||||
{
|
||||
value = "/" + value;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
23
yy-admin-master/YY.Admin/Helper/WebView2UserDataFolder.cs
Normal file
23
yy-admin-master/YY.Admin/Helper/WebView2UserDataFolder.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.IO;
|
||||
using Microsoft.Web.WebView2.Wpf;
|
||||
using YY.Admin.Core.Util;
|
||||
|
||||
namespace YY.Admin.Helper;
|
||||
|
||||
/// <summary>
|
||||
/// WebView2 默认将用户数据目录放在宿主 exe 旁边;安装在 Program Files 时目录只读会导致初始化失败、预览白屏。
|
||||
/// 统一到当前用户 LocalAppData 下的可写路径。
|
||||
/// </summary>
|
||||
public static class WebView2UserDataFolder
|
||||
{
|
||||
/// <summary>
|
||||
/// 为控件创建 CreationProperties(须在首次 EnsureCoreWebView2Async 之前赋值)。
|
||||
/// </summary>
|
||||
/// <param name="subFolder">子目录名,避免不同场景争用同一 profile。</param>
|
||||
public static CoreWebView2CreationProperties CreateCreationProperties(string subFolder)
|
||||
{
|
||||
var folder = AppWritablePaths.EnsureDirectoryExists(
|
||||
Path.Combine(AppWritablePaths.LocalApplicationRoot, "WebView2", subFolder));
|
||||
return new CoreWebView2CreationProperties { UserDataFolder = folder };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user