You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
10 KiB
C#

2 months ago
using Autofac.Extensions.DependencyInjection;
using Lierda.WPFHelper;
2 years ago
using Microsoft.AspNetCore.Hosting;
2 months ago
using Microsoft.Extensions.Configuration;
2 years ago
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using SlnMesnac.Config;
using SlnMesnac.Plc;
using SlnMesnac.Rfid;
2 months ago
using System;
using System.Collections.Generic;
using System.Windows;
2 years ago
namespace SlnMesnac.WPF
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private System.Threading.Mutex? mutex = null;
private LierdaCracker cracker = new LierdaCracker();
public static IServiceProvider? ServiceProvider = null;
2 months ago
private static IHost? host;
private AppConfig appConfig;
2 years ago
// Startup事件
protected override async void OnStartup(StartupEventArgs e)
{
1 year ago
try
2 years ago
{
1 year ago
bool ret;
2 months ago
//mutex = new System.Threading.Mutex(true, System.Diagnostics.Process.GetCurrentProcess().ProcessName, out ret);
//if (!ret)
//{
// MessageBox.Show("应用程序已开启,禁止重复运行");
// Environment.Exit(0);
//}
2 years ago
1 year ago
cracker.Cracker(100); //设置GC回收间隔
2 years ago
1 year ago
base.OnStartup(e);
2 months ago
//var host = CreateHostBuilder(e.Args).Build();//生成宿主。
//ServiceProvider = host.Services;
//await host.StartAsync();
var instanceId = GetInstanceId(e.Args);
// 创建完全独立的Host构建器
host = CreateHostBuilder(e.Args, instanceId).Build();
// 预先验证服务
using (var scope = host.Services.CreateScope())
{
ServiceProvider = scope.ServiceProvider;
try
{
2 years ago
2 months ago
//serilogHelper = services.GetRequiredService<SerilogHelper>();
//serilogHelper.Info($"启动服务");
//var appConfig = services.GetRequiredService<AppConfig>();
appConfig = host.Services.GetService<AppConfig>();
2 years ago
2 months ago
// 强制设置实例ID到配置对象
SetInstanceSpecificConfiguration(appConfig, instanceId);
2 years ago
2 months ago
//serilogHelper.Info($"实例 {instanceId} 服务初始化完成");
Console.WriteLine($"实例 {instanceId} 服务初始化完成");
}
catch (Exception ex)
{
Console.WriteLine($"实例 {instanceId} 服务初始化失败: {ex.Message}");
//serilogHelper.Info($"详细错误: {ex}");
}
}
//await host.StartAsync();
var hostTask = host.RunAsync();
1 year ago
var logPath = $"{appConfig.logPath}/Logs/{DateTime.UtcNow:yyyy-MM-dd}/";
Log.Information($"系统初始化完成,日志存放路径:{appConfig.logPath}");
}
catch (Exception exception)
{
Console.WriteLine(exception);
throw;
}
2 years ago
}
2 months ago
private static void SetInstanceSpecificConfiguration(AppConfig appConfig, string instanceId)
{
try
{
Console.WriteLine($"为实例 {instanceId} 设置特定配置...");
// 使用反射设置所有可能的配置属性
var configType = appConfig.GetType();
var properties = configType.GetProperties();
foreach (var property in properties)
{
if (property.CanWrite)
{
var value = property.GetValue(appConfig);
if (value is string stringValue)
{
// 替换路径中的占位符
if (stringValue.Contains("{Instance}") ||
stringValue.Contains("{instance}"))
{
var newValue = stringValue
.Replace("{Instance}", instanceId)
.Replace("{instance}", instanceId);
property.SetValue(appConfig, newValue);
Console.WriteLine($" 更新 {property.Name}: {newValue}");
}
else if (IsPathProperty(property.Name) &&
!stringValue.Contains(instanceId))
{
// 为路径属性添加实例ID
var newValue = $"{stringValue}_Instance{instanceId}";
property.SetValue(appConfig, newValue);
Console.WriteLine($" 更新 {property.Name}: {newValue}");
}
}
else if (property.PropertyType == typeof(int) &&
IsPortProperty(property.Name))
{
// 调整端口号
var basePort = (int)value;
var newPort = basePort + (int.Parse(instanceId) - 1) * 10;
property.SetValue(appConfig, newPort);
Console.WriteLine($" 更新 {property.Name}: {newPort}");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"设置实例配置时出错: {ex.Message}");
//serilogHelper?.Info($"设置实例配置时出错: {ex.Message}");
}
}
private static bool IsPortProperty(string propertyName)
{
return propertyName.ToLower().Contains("port");
}
private static bool IsPathProperty(string propertyName)
{
return propertyName.ToLower().Contains("path") ||
propertyName.ToLower().Contains("dir") ||
propertyName.ToLower().Contains("file");
}
public static IHostBuilder CreateHostBuilder(string[] args, string instanceId) =>
Host.CreateDefaultBuilder(args)
.UseSerilog((context, config) =>
{
// 为每个实例配置独立的Serilog
config.WriteTo.Console(
outputTemplate: $"[{{Timestamp:HH:mm:ss}} {{Level:u3}}] Instance{instanceId}: {{Message:lj}}{{NewLine}}{{Exception}}")
.WriteTo.File(
path: $"./Logs/{DateTime.UtcNow:yyyy-MM-dd}/log-.txt",
rollingInterval: RollingInterval.Day,
outputTemplate: $"[{{Timestamp:yyyy-MM-dd HH:mm:ss}} {{Level:u3}}] Instance{instanceId}: {{Message:lj}}{{NewLine}}{{Exception}}");
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration((context, config) =>
{
// 清除默认配置,从头开始构建
config.Sources.Clear();
// 按优先级添加配置源
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.instance{instanceId}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables("INSTANCE_")
.AddCommandLine(args);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureKestrel(serverOptions =>
{
Console.WriteLine(int.Parse(instanceId));
serverOptions.ListenAnyIP(1 + (int.Parse(instanceId) - 1));
});
})
.ConfigureServices((context, services) =>
{
services.AddSingleton(new InstanceInfo { Id = instanceId });
});
public class InstanceInfo
{
public string Id { get; set; } = "1";
}
private static string GetInstanceId(string[] args)
{
// 支持多种参数格式
foreach (var arg in args)
{
if (arg.StartsWith("--instance"))
{
if (arg == "--instance")
{
// 查找下一个参数作为实例ID
var index = Array.IndexOf(args, arg);
if (index + 1 < args.Length)
{
return args[index + 1];
}
}
else if (arg.StartsWith("--instance="))
{
return arg.Substring("--instance=".Length);
}
else
{
// 格式: --instance1, --instance2
return arg.Substring("--instance".Length);
}
}
}
2 years ago
2 months ago
// 如果没有指定实例ID使用随机ID避免冲突
Random random = new Random();
return random.Next(0000, 9999).ToString();
}
2 years ago
/// <summary>
/// CreateHostBuilder
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
2 months ago
2 years ago
.UseSerilog()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
// Exit事件
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
Log.Information($"系统退出,当前时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
// 释放资源
// ...
}
}
}