using cmonitor.api; using cmonitor.api.services; using cmonitor.client; using cmonitor.client.reports.active; using cmonitor.client.reports.light; using cmonitor.client.reports.hijack; using cmonitor.client.reports.llock; using cmonitor.client.reports.screen; using cmonitor.client.reports.volume; using cmonitor.client.reports.notify; using cmonitor.client.reports.command; using cmonitor.client.reports; using cmonitor.client.reports.share; using cmonitor.client.reports.system; using cmonitor.service; using cmonitor.service.messengers.active; using cmonitor.service.messengers.hijack; using cmonitor.service.messengers.llock; using cmonitor.service.messengers.report; using cmonitor.service.messengers.screen; using cmonitor.service.messengers.sign; using cmonitor.service.messengers.volume; using cmonitor.service.messengers.wallpaper; using cmonitor.service.messengers.keyboard; using cmonitor.service.messengers.system; using cmonitor.service.messengers.light; using cmonitor.service.messengers.share; using cmonitor.service.messengers.notify; using cmonitor.service.messengers.setting; using cmonitor.web; using common.libs; using common.libs.database; using common.libs.extends; using Microsoft.Extensions.DependencyInjection; using System.Net; using System.Reflection; using System.Text.Json.Serialization; using cmonitor.client.reports.keyboard; using cmonitor.client.reports.wallpaper; using cmonitor.client.reports.snatch; using cmonitor.service.messengers.snatch; using cmonitor.libs; namespace cmonitor { internal class Program { static async Task Main(string[] args) { //单服务 Mutex mutex = new Mutex(true, System.Diagnostics.Process.GetCurrentProcess().ProcessName, out bool isAppRunning); if (isAppRunning == false) { Environment.Exit(1); } //日志输出 LoggerConsole(); /* foreach (var arg in Dns.GetHostByName(Dns.GetHostName()).AddressList) { Console.WriteLine(arg.Address.ToString()); }*/ //读取参数 Dictionary dic = ArgumentParser.Parse(args, out string error); #if RELEASE //提权 if (dic.ContainsKey("elevated") == false) { Win32Interop.RelaunchElevated(); } #endif //初始化配置文件 Config config = new Config(); InitConfig(config, dic); //全局异常 AppDomain.CurrentDomain.UnhandledException += (a, b) => { Logger.Instance.Error(b.ExceptionObject + ""); }; //线程数 ThreadPool.SetMinThreads(1024, 1024); ThreadPool.SetMaxThreads(65535, 65535); //注入对象 ServiceProvider serviceProvider = null; ServiceCollection serviceCollection = new ServiceCollection(); //注入 依赖注入服务供应 使得可以在别的地方通过注入的方式获得 ServiceProvider 以用来获取其它服务 serviceCollection.AddSingleton((e) => serviceProvider); //注入 serviceCollection.AddSingleton((a) => config); AddSingleton(serviceCollection, config); serviceProvider = serviceCollection.BuildServiceProvider(); //运行服务 RunService(serviceProvider, config); GCHelper.FlushMemory(); await Helper.Await(); } private static void RunService(ServiceProvider serviceProvider, Config config) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); MessengerResolver messengerResolver = serviceProvider.GetService(); messengerResolver.LoadMessenger(assemblies); if (config.IsServer) { Logger.Instance.Info($"start server"); //api IClientServer clientServer = serviceProvider.GetService(); clientServer.LoadPlugins(assemblies); clientServer.Websocket(); Logger.Instance.Info($"api listen:{config.ApiPort}"); //web IWebServer webServer = serviceProvider.GetService(); webServer.Start(); Logger.Instance.Info($"web listen:{config.WebPort}"); //服务 TcpServer tcpServer = serviceProvider.GetService(); tcpServer.Start(); Logger.Instance.Info($"service listen:{config.ServicePort}"); } if (config.IsCLient) { Logger.Instance.Info($"start client"); Logger.Instance.Info($"server ip {config.Server}"); ReportTransfer report = serviceProvider.GetService(); report.LoadPlugins(assemblies); ShareMemory shareMemory = serviceProvider.GetService(); shareMemory.InitLocal(); shareMemory.InitGlobal(); shareMemory.StartLoop(); ClientTransfer clientTransfer = serviceProvider.GetService(); } } private static void AddSingleton(ServiceCollection serviceCollection, Config config) { serviceCollection.AddTransient(typeof(IConfigDataProvider<>), typeof(ConfigDataFileProvider<>)); //客户端 serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); //内存共享 ShareMemory shareMemory = new ShareMemory(config.ShareMemoryKey, config.ShareMemoryLength, config.ShareMemoryItemSize); serviceCollection.AddSingleton((a) => shareMemory); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton(); else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); //服务 serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); //api serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); //web serviceCollection.AddSingleton(); } private static void InitConfig(Config config, Dictionary dic) { try { config.Server = IPAddress.Parse(dic["server"]); config.Name = dic["name"]; config.WebPort = int.Parse(dic["web"]); config.ApiPort = int.Parse(dic["api"]); config.ServicePort = int.Parse(dic["service"]); config.ShareMemoryKey = dic["share-key"]; config.ShareMemoryLength = int.Parse(dic["share-len"]); config.ShareMemoryItemSize = int.Parse(dic["share-item-len"]); config.ReportDelay = int.Parse(dic["report-delay"]); config.ScreenScale = float.Parse(dic["screen-scale"]); config.ScreenDelay = int.Parse(dic["screen-delay"]); config.Elevated = dic.ContainsKey("elevated"); Logger.Instance.Debug($"config:{config.ToJsonFormat()}"); //Logger.Instance.Debug($"args:{string.Join(" ", args)}"); config.IsCLient = dic.ContainsKey("mode") && dic["mode"].Contains("client"); config.IsServer = dic.ContainsKey("mode") && dic["mode"].Contains("server"); } catch (Exception ex) { Logger.Instance.Error(ex); } } private static void LoggerConsole() { Logger.Instance.LoggerLevel = LoggerTypes.DEBUG; if (Directory.Exists("log") == false) { Directory.CreateDirectory("log"); } Logger.Instance.OnLogger += (model) => { ConsoleColor currentForeColor = Console.ForegroundColor; switch (model.Type) { case LoggerTypes.DEBUG: Console.ForegroundColor = ConsoleColor.Blue; break; case LoggerTypes.INFO: Console.ForegroundColor = ConsoleColor.White; break; case LoggerTypes.WARNING: Console.ForegroundColor = ConsoleColor.Yellow; break; case LoggerTypes.ERROR: Console.ForegroundColor = ConsoleColor.Red; break; default: break; } string line = $"[{model.Type,-7}][{model.Time:yyyy-MM-dd HH:mm:ss}]:{model.Content}"; Console.WriteLine(line); Console.ForegroundColor = currentForeColor; try { using StreamWriter sw = File.AppendText(Path.Combine("log", $"{DateTime.Now:yyyy-MM-dd}.log")); sw.WriteLine(line); sw.Flush(); sw.Close(); sw.Dispose(); } catch (Exception) { } }; } } public sealed class Config { public int WebPort { get; set; } = 1800; public int ApiPort { get; set; } = 1801; public int ServicePort { get; set; } = 1802; public IPAddress Server { get; set; } = IPAddress.Loopback; public string WebRoot { get; set; } = "./web/"; public string Name { get; set; } = Dns.GetHostName(); public int ReportDelay { get; set; } = 30; public float ScreenScale { get; set; } = 0.2f; public int ScreenDelay { get; set; } = 30; /// /// 0项保留 /// public string ShareMemoryKey { get; set; } = "cmonitor/share"; public int ShareMemoryLength { get; set; } = 10; public int ShareMemoryItemSize { get; set; } = 1024; [JsonIgnore] public bool SaveSetting { get; set; } = true; [JsonIgnore] public bool WakeUp { get; set; } = true; [JsonIgnore] public bool VolumeMasterPeak { get; set; } = false; [JsonIgnore] public string Version { get; set; } = "1.0.0.1"; [JsonIgnore] public bool IsCLient { get; set; } [JsonIgnore] public bool IsServer { get; set; } [JsonIgnore] public bool Elevated { get; set; } //键盘 public const int ShareMemoryKeyBoardIndex = 1; //壁纸 public const int ShareMemoryWallpaperIndex = 2; //锁屏 public const int ShareMemoryLLockIndex = 3; //SAS public const int ShareMemorySASIndex = 4; //抢答,问题,和回答分开存,为了保证数据安全性 public const int ShareSnatchQuestionIndex = 5; public const int ShareSnatchAnswerIndex = 6; public const int ShareScreenShareIndex = 7; } public class ArgumentParser { public static Dictionary Parse(string[] args, out string error) { Dictionary dic = new Dictionary(); for (int i = 0; i < args.Length; i++) { if (args[i].IndexOf("--") == 0) { if (i + 1 < args.Length && args[i + 1].IndexOf("--") == -1) { dic.Add(args[i].Substring(2), args[i + 1]); i++; } else { dic.Add(args[i].Substring(2), string.Empty); } } } Validate(dic, out error); return dic; } static bool Validate(Dictionary dic, out string error) { error = string.Empty; return ValidateMode(dic) && ValidateServer(dic, out error) && ValidateName(dic, out error) && ValidatePort(dic, out error) && ValidateMemoryKey(dic, out error) && ValidateScreenScale(dic, out error) && ValidateReport(dic, out error) && ValidateElevated(dic, out error); } static bool ValidateMode(Dictionary dic) { //模式 if (dic.ContainsKey("mode") == false || (dic["mode"].Contains("client") == false && dic["mode"].Contains("server") == false)) { dic["mode"] = "server,client"; } return true; } static bool ValidateServer(Dictionary dic, out string error) { error = string.Empty; //服务器地址 if (dic.ContainsKey("server") == false || string.IsNullOrWhiteSpace(dic["server"])) { dic["server"] = IPAddress.Loopback.ToString(); } return true; } static bool ValidateName(Dictionary dic, out string error) { error = string.Empty; //服务器地址 if (dic.ContainsKey("name") == false || string.IsNullOrWhiteSpace(dic["name"])) { dic["name"] = Dns.GetHostName(); if (dic["name"].Length > 12) { dic["name"] = dic["name"].Substring(0, 12); } } return true; } static bool ValidatePort(Dictionary dic, out string error) { error = string.Empty; //界面接口 if (dic.ContainsKey("web") == false || string.IsNullOrWhiteSpace(dic["web"])) { dic["web"] = "1800"; } //管理接口 if (dic.ContainsKey("api") == false || string.IsNullOrWhiteSpace(dic["api"])) { dic["api"] = "1801"; } //服务接口 if (dic.ContainsKey("service") == false || string.IsNullOrWhiteSpace(dic["service"])) { dic["service"] = "1802"; } return true; } static bool ValidateMemoryKey(Dictionary dic, out string error) { error = string.Empty; if (dic.ContainsKey("share-key") == false || string.IsNullOrWhiteSpace(dic["share-key"])) { dic["share-key"] = "cmonitor/share"; } if (dic.ContainsKey("share-len") == false || string.IsNullOrWhiteSpace(dic["share-len"])) { dic["share-len"] = "10"; } if (dic.ContainsKey("share-item-len") == false || string.IsNullOrWhiteSpace(dic["share-item-len"])) { dic["share-item-len"] = "1024"; } return true; } static bool ValidateScreenScale(Dictionary dic, out string error) { error = string.Empty; if (dic.ContainsKey("screen-scale") == false || string.IsNullOrWhiteSpace(dic["screen-scale"])) { dic["screen-scale"] = "0.2"; } if (dic.ContainsKey("screen-delay") == false || string.IsNullOrWhiteSpace(dic["screen-delay"])) { dic["screen-delay"] = "200"; } return true; } static bool ValidateReport(Dictionary dic, out string error) { error = string.Empty; if (dic.ContainsKey("report-delay") == false || string.IsNullOrWhiteSpace(dic["report-delay"])) { dic["report-delay"] = "30"; } return true; } static bool ValidateElevated(Dictionary dic, out string error) { error = string.Empty; if (dic.ContainsKey("elevated")) { dic["elevated"] = "1"; } return true; } } }