/// <summary> /// 如果给定的服务器版本比本地版本高则发布AppVersionChangedEvent事件 /// </summary> /// <param name="serverVersion"></param> public static void PublishIfNewVersion(string serverVersion) { if (!string.IsNullOrEmpty(serverVersion) && serverVersion != NTMinerRoot.CurrentVersion.ToString()) { NTMinerRoot.ServerVersion = serverVersion; VirtualRoot.Happened(new AppVersionChangedEvent()); } }
// MinerProfile对应local.litedb或local.json public void ReInitMinerProfile() { ReInitLocalJson(); this._minerProfile.ReInit(this, LocalJson.MineWork); // 本地数据集已刷新,此时刷新本地数据集的视图模型集 VirtualRoot.Happened(new LocalContextReInitedEvent()); // 本地数据集的视图模型已刷新,此时刷新本地数据集的视图界面 VirtualRoot.Happened(new LocalContextVmsReInitedEvent()); RefreshArgsAssembly(); }
private static void Continue(IMineContext mineContext) { Thread.Sleep(1000); if (mineContext != Instance.CurrentMineContext) { Write.UserWarn("挖矿停止"); return; } // 解压内核包 if (!mineContext.Kernel.ExtractPackage()) { VirtualRoot.Happened(new StartingMineFailedEvent("内核解压失败,请卸载内核重试。")); } else { Write.UserOk("内核包解压成功"); } // 执行文件书写器 mineContext.ExecuteFileWriters(); // 分离命令名和参数 GetCmdNameAndArguments(mineContext, out string kernelExeFileFullName, out string arguments); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Write.UserError(kernelExeFileFullName + "文件不存在,可能是小编拼写错误或是挖矿内核被杀毒软件删除导致,请退出杀毒软件重试或者QQ群联系小编。"); } if (mineContext.KernelProcessType == KernelProcessType.Logfile) { arguments = arguments.Replace("{logfile}", mineContext.LogFileFullName); } Write.UserOk($"\"{kernelExeFileFullName}\" {arguments}"); Write.UserInfo($"有请内核上场:{mineContext.KernelProcessType}"); if (mineContext != Instance.CurrentMineContext) { Write.UserWarn("挖矿停止"); return; } switch (mineContext.KernelProcessType) { case KernelProcessType.Logfile: CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); break; case KernelProcessType.Pip: CreatePipProcess(mineContext, kernelExeFileFullName, arguments); break; default: throw new InvalidProgramException(); } VirtualRoot.Happened(new MineStartedEvent(mineContext)); }
private void SetServerJsonVersion(string serverJsonVersion) { AppSettingData appSettingData = new AppSettingData() { Key = "ServerJsonVersion", Value = serverJsonVersion }; string oldVersion = GetServerJsonVersion(); VirtualRoot.Execute(new ChangeLocalAppSettingCommand(appSettingData)); VirtualRoot.Happened(new ServerJsonVersionChangedEvent(oldVersion, serverJsonVersion)); }
public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { try { Windows.TaskKill.Kill(mineContext.Kernel.GetProcessName(), waitForExit: true); Thread.Sleep(1000); if (_preExtractPackage != mineContext.Kernel.Package) { _preExtractPackage = mineContext.Kernel.Package; Logger.InfoDebugLine("解压内核包"); // 解压内核包 if (!mineContext.Kernel.ExtractPackage()) { VirtualRoot.Happened(new StartingMineFailedEvent("内核解压失败。")); } } Logger.InfoDebugLine("组装命令"); // 组装命令 BuildCmdLine(mineContext, out var kernelExeFileFullName, out var arguments); bool isLogFile = arguments.Contains("{logfile}"); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Logger.ErrorDebugLine(kernelExeFileFullName + "文件不存在,请检查是否有拼写错误"); } if (isLogFile) { Logger.InfoDebugLine("创建日志文件型进程"); // 如果内核支持日志文件 // 推迟打印cmdLine,因为{logfile}变量尚未求值 CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); } else { Logger.InfoDebugLine("创建管道型进程"); // 如果内核不支持日志文件 CreatePipProcess(mineContext, kernelExeFileFullName, arguments); } Write.UserOk("开始挖矿"); VirtualRoot.Happened(new MineStartedEvent(mineContext)); } catch (Exception e) { Logger.ErrorDebugLine(e.Message, e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } }); }
public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { try { Windows.TaskKill.Kill(mineContext.Kernel.GetProcessName()); Thread.Sleep(1000); Logger.InfoDebugLine("解压内核包"); // 解压内核包 mineContext.Kernel.ExtractPackage(); Logger.InfoDebugLine("组装命令"); // 组装命令 BuildCmdLine(mineContext, out var kernelExeFileFullName, out var arguments); bool isLogFile = arguments.Contains("{logfile}"); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Logger.ErrorDebugLine(kernelExeFileFullName + "文件不存在,请检查是否有拼写错误"); } if (isLogFile) { Logger.InfoDebugLine("创建日志文件型进程"); // 如果内核支持日志文件 // 推迟打印cmdLine,因为{logfile}变量尚未求值 CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); } else { Logger.InfoDebugLine("创建管道型进程"); // 如果内核不支持日志文件 string cmdLine = $"\"{kernelExeFileFullName}\" {arguments}"; Logger.InfoDebugLine(cmdLine); CreatePipProcess(mineContext, cmdLine); } VirtualRoot.Happened(new MineStartedEvent(mineContext)); } catch (Exception e) { Logger.ErrorDebugLine(e.Message, e); } }); }
private void ContextReInit(bool isWork) { foreach (var handler in _serverContextHandlers) { VirtualRoot.UnPath(handler); } _serverContextHandlers.Clear(); if (isWork) { ReInitServerJson(); } ServerContextInit(isWork); // CoreContext的视图模型集此时刷新 VirtualRoot.Happened(new ServerContextReInitedEvent()); // CoreContext的视图模型集已全部刷新,此时刷新视图界面 VirtualRoot.Happened(new ServerContextVmsReInitedEvent()); if (isWork) { ReInitMinerProfile(); } }
private void ShowMainWindow(bool isToggle) { UIThread.Execute(() => { _appViewFactory.ShowMainWindow(isToggle); // 使状态栏显示显示最新状态 if (NTMinerRoot.Instance.IsMining) { var mainCoin = NTMinerRoot.Instance.CurrentMineContext.MainCoin; if (mainCoin == null) { return; } var coinShare = NTMinerRoot.Instance.CoinShareSet.GetOrCreate(mainCoin.GetId()); VirtualRoot.Happened(new ShareChangedEvent(coinShare)); if ((NTMinerRoot.Instance.CurrentMineContext is IDualMineContext dualMineContext) && dualMineContext.DualCoin != null) { coinShare = NTMinerRoot.Instance.CoinShareSet.GetOrCreate(dualMineContext.DualCoin.GetId()); VirtualRoot.Happened(new ShareChangedEvent(coinShare)); } AppContext.Instance.GpuSpeedVms.Refresh(); } }); }
// 创建管道,将输出通过管道转送到日志文件,然后读取日志文件内容打印到控制台 private static void CreatePipProcess(IMineContext mineContext, string kernelExeFileFullName, string arguments) { SECURITY_ATTRIBUTES saAttr = new SECURITY_ATTRIBUTES { bInheritHandle = true, lpSecurityDescriptor = IntPtr.Zero, length = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES)) }; //set the bInheritHandle flag so pipe handles are inherited saAttr.lpSecurityDescriptor = IntPtr.Zero; //get handle to current stdOut IntPtr mypointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(STARTUPINFO))); Marshal.StructureToPtr(saAttr, mypointer, true); var bret = CreatePipe(out var hReadOut, out var hWriteOut, mypointer, 0); //ensure the read handle to pipe for stdout is not inherited SetHandleInformation(hReadOut, HANDLE_FLAG_INHERIT, 0); ////Create pipe for the child process's STDIN STARTUPINFO lpStartupInfo = new STARTUPINFO { cb = (uint)Marshal.SizeOf(typeof(STARTUPINFO)), dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW, wShowWindow = SW_HIDE, // SW_HIDE; //SW_SHOW hStdOutput = hWriteOut, hStdError = hWriteOut, hStdInput = IntPtr.Zero }; string cmdLine = $"\"{kernelExeFileFullName}\" {arguments}"; Write.UserOk(cmdLine); Write.UserInfo("有请内核上场"); StringBuilder lpEnvironment = new StringBuilder(); // 复制父进程的环境变量 IDictionary dic = Environment.GetEnvironmentVariables(); // 追加环境变量 foreach (var item in mineContext.CoinKernel.EnvironmentVariables) { dic.Add(item.Key, item.Value); } foreach (var key in dic.Keys) { if (key == null || key.ToString().Contains("\0")) { continue; } var value = dic[key]; if (value == null || value.ToString().Contains("\0")) { continue; } lpEnvironment.Append($"{key.ToString()}={value.ToString()}\0"); } if (CreateProcess( lpApplicationName: null, lpCommandLine: new StringBuilder(cmdLine), lpProcessAttributes: IntPtr.Zero, lpThreadAttributes: IntPtr.Zero, bInheritHandles: true, dwCreationFlags: NORMAL_PRIORITY_CLASS, lpEnvironment: lpEnvironment, lpCurrentDirectory: Path.GetDirectoryName(kernelExeFileFullName), lpStartupInfo: ref lpStartupInfo, lpProcessInformation: out _)) { if (bret == false) { int lasterr = Marshal.GetLastWin32Error(); VirtualRoot.Happened(new StartingMineFailedEvent($"管道型进程创建失败 lasterr:{lasterr}")); } else { Bus.DelegateHandler <MineStopedEvent> closeHandle = null; bool isHWriteOutHasClosed = false; Daemon(mineContext, () => { if (!isHWriteOutHasClosed) { CloseHandle(hWriteOut); isHWriteOutHasClosed = true; } VirtualRoot.UnPath(closeHandle); }); closeHandle = VirtualRoot.On <MineStopedEvent>("挖矿停止后关闭非托管的日志句柄", LogEnum.DevConsole, action: message => { // 挖矿停止后摘除挖矿内核进程守护器 if (_sDaemon != null) { VirtualRoot.UnPath(_sDaemon); _sDaemon = null; } if (!isHWriteOutHasClosed) { CloseHandle(hWriteOut); isHWriteOutHasClosed = true; } VirtualRoot.UnPath(closeHandle); }); string pipLogFileFullName = Path.Combine(SpecialPath.LogsDirFullName, mineContext.PipeFileName); Task.Factory.StartNew(() => { FileStream fs = new FileStream(pipLogFileFullName, FileMode.OpenOrCreate, FileAccess.ReadWrite); using (StreamReader sr = new StreamReader(fs)) { byte[] buffer = new byte[1024]; int ret; // Read会阻塞,直到读取到字符或者hWriteOut被关闭 while ((ret = Read(buffer, 0, buffer.Length, hReadOut)) > 0) { fs.Write(buffer, 0, ret); if (buffer[ret - 1] == '\r' || buffer[ret - 1] == '\n') { fs.Flush(); } } } CloseHandle(hReadOut); }, TaskCreationOptions.LongRunning); ReadPrintLoopLogFileAsync(mineContext, pipLogFileFullName); } } else { VirtualRoot.Happened(new StartingMineFailedEvent($"内核启动失败,请重试")); } }
public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { lock (_locker) { try { Write.UserInfo("清理内核进程"); #if DEBUG VirtualRoot.Stopwatch.Restart(); #endif // 清理除当前外的Temp/Kernel Cleaner.Clear(); #if DEBUG Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {nameof(MinerProcess)}.{nameof(CreateProcessAsync)}[{nameof(Cleaner)}.{nameof(Cleaner.Clear)}]"); #endif Write.UserOk("内核进程清理完毕"); Thread.Sleep(1000); Write.UserInfo($"解压内核包{mineContext.Kernel.Package}"); // 解压内核包 if (!mineContext.Kernel.ExtractPackage()) { VirtualRoot.Happened(new StartingMineFailedEvent("内核解压失败,请卸载内核重试。")); } else { Write.UserOk("内核包解压成功"); } // 执行文件书写器 mineContext.ExecuteFileWriters(); Write.UserInfo("总成命令"); // 组装命令 BuildCmdLine(mineContext, out string kernelExeFileFullName, out string arguments); bool isLogFile = arguments.Contains("{logfile}"); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Write.UserError(kernelExeFileFullName + "文件不存在,可能是小编拼写错误导致,请QQ群联系小编。"); } if (isLogFile) { Logger.InfoDebugLine("创建日志文件型进程"); // 如果内核支持日志文件 // 推迟打印cmdLine,因为{logfile}变量尚未求值 CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); } else { Logger.InfoDebugLine("创建管道型进程"); // 如果内核不支持日志文件 CreatePipProcess(mineContext, kernelExeFileFullName, arguments); } VirtualRoot.Happened(new MineStartedEvent(mineContext)); } catch (Exception e) { Logger.ErrorDebugLine(e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } } }); }
public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { lock (_locker) { try { Write.UserInfo("清理内核进程"); HashSet <string> allKernelProcessNames = Instance.KernelSet.GetAllKernelProcessNames(); #if DEBUG VirtualRoot.Stopwatch.Restart(); #endif foreach (var processName in allKernelProcessNames) { Windows.TaskKill.Kill(processName, waitForExit: true); } #if DEBUG Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {nameof(MinerProcess)}.{nameof(CreateProcessAsync)}[{nameof(allKernelProcessNames)}]"); #endif Write.UserOk("内核进程清理完毕"); Thread.Sleep(1000); Write.UserInfo($"解压内核包{mineContext.Kernel.Package}"); // 解压内核包 if (!mineContext.Kernel.ExtractPackage()) { Write.UserFail("内核解压失败"); VirtualRoot.Happened(new StartingMineFailedEvent("内核解压失败。")); } else { Write.UserOk("内核包解压成功"); } Write.UserInfo("总成命令"); // 组装命令 BuildCmdLine(mineContext, out var kernelExeFileFullName, out var arguments); bool isLogFile = arguments.Contains("{logfile}"); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Write.UserError(kernelExeFileFullName + "文件不存在,可能是小编拼写错误导致,请QQ群联系小编。"); } if (isLogFile) { Logger.InfoDebugLine("创建日志文件型进程"); // 如果内核支持日志文件 // 推迟打印cmdLine,因为{logfile}变量尚未求值 CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); } else { Logger.InfoDebugLine("创建管道型进程"); // 如果内核不支持日志文件 CreatePipProcess(mineContext, kernelExeFileFullName, arguments); } VirtualRoot.Happened(new MineStartedEvent(mineContext)); } catch (Exception e) { Logger.ErrorDebugLine(e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } } }); }
private void Link() { VirtualRoot.Window <RegCmdHereCommand>("处理注册右键打开windows命令行菜单命令", LogEnum.DevConsole, action: message => { try { RegCmdHere(); VirtualRoot.Happened(new RegCmdHereEvent(true, "windows右键命令行添加成功")); } catch (Exception e) { Logger.ErrorDebugLine(e); VirtualRoot.Happened(new RegCmdHereEvent(false, "windows右键命令行添加失败")); } }); #region 挖矿开始时将无份额内核重启份额计数置0 int shareCount = 0; DateTime shareOn = DateTime.Now; VirtualRoot.On <MineStartedEvent>("挖矿开始后将无份额内核重启份额计数置0", LogEnum.DevConsole, action: message => { // 将无份额内核重启份额计数置0 shareCount = 0; if (!message.MineContext.IsRestart) { shareOn = DateTime.Now; } }); #endregion #region 每20秒钟检查是否需要重启 VirtualRoot.On <Per20SecondEvent>("每20秒钟检查是否需要重启", LogEnum.None, action: message => { #region 重启电脑 try { if (MinerProfile.IsPeriodicRestartComputer) { if ((DateTime.Now - this.CreatedOn).TotalMinutes > 60 * MinerProfile.PeriodicRestartComputerHours + MinerProfile.PeriodicRestartComputerMinutes) { Logger.WarnWriteLine($"每运行{MinerProfile.PeriodicRestartKernelHours}小时{MinerProfile.PeriodicRestartComputerMinutes}分钟重启电脑"); Windows.Power.Restart(60); VirtualRoot.Execute(new CloseNTMinerCommand()); return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(e); } #endregion #region 周期重启内核 try { if (IsMining && MinerProfile.IsPeriodicRestartKernel) { if ((DateTime.Now - CurrentMineContext.CreatedOn).TotalMinutes > 60 * MinerProfile.PeriodicRestartKernelHours + MinerProfile.PeriodicRestartKernelMinutes) { Logger.WarnWriteLine($"每运行{MinerProfile.PeriodicRestartKernelHours}小时{MinerProfile.PeriodicRestartKernelMinutes}分钟重启内核"); RestartMine(); return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(e); } #endregion #region 收益没有增加重启内核 try { if (IsMining && this.CurrentMineContext.MainCoin != null) { int totalShare = 0; bool restartComputer = MinerProfile.IsNoShareRestartComputer && (DateTime.Now - shareOn).TotalMinutes > MinerProfile.NoShareRestartComputerMinutes; bool restartKernel = MinerProfile.IsNoShareRestartKernel && (DateTime.Now - shareOn).TotalMinutes > MinerProfile.NoShareRestartKernelMinutes; if (restartComputer || restartKernel) { ICoinShare mainCoinShare = this.CoinShareSet.GetOrCreate(this.CurrentMineContext.MainCoin.GetId()); totalShare = mainCoinShare.TotalShareCount; if ((this.CurrentMineContext is IDualMineContext dualMineContext) && dualMineContext.DualCoin != null) { ICoinShare dualCoinShare = this.CoinShareSet.GetOrCreate(dualMineContext.DualCoin.GetId()); totalShare += dualCoinShare.TotalShareCount; } // 如果份额没有增加 if (shareCount == totalShare) { if (restartComputer) { if (!NTMinerRegistry.GetIsAutoBoot()) { NTMinerRegistry.SetIsAutoBoot(true); } if (!NTMinerRegistry.GetIsAutoStart()) { NTMinerRegistry.SetIsAutoStart(true); } Logger.WarnWriteLine($"{MinerProfile.NoShareRestartComputerMinutes}分钟收益没有增加重启电脑"); Windows.Power.Restart(60); VirtualRoot.Execute(new CloseNTMinerCommand()); return; // 退出 } // 产生过份额或者已经两倍重启内核时间了 if (restartKernel && (totalShare > 0 || (DateTime.Now - shareOn).TotalMinutes > 2 * MinerProfile.NoShareRestartKernelMinutes)) { Logger.WarnWriteLine($"{MinerProfile.NoShareRestartKernelMinutes}分钟收益没有增加重启内核"); RestartMine(); return; // 退出 } } if (totalShare > shareCount) { shareCount = totalShare; shareOn = DateTime.Now; } }
public void Start() { OfficialServer.GetTimeAsync((remoteTime) => { if (Math.Abs((DateTime.Now - remoteTime).TotalSeconds) < Timestamp.DesyncSeconds) { Logger.OkDebugLine("时间同步"); } else { Logger.WarnDebugLine($"本机时间和服务器时间不同步,请调整,本地:{DateTime.Now},服务器:{remoteTime}"); } }); Report.Init(this); VirtualRoot.Window <RegCmdHereCommand>("处理注册右键打开windows命令行菜单命令", LogEnum.DevConsole, action: message => { string cmdHere = "SOFTWARE\\Classes\\Directory\\background\\shell\\cmd_here"; string cmdHereCommand = cmdHere + "\\command"; string cmdPrompt = "SOFTWARE\\Classes\\Folder\\shell\\cmdPrompt"; string cmdPromptCommand = cmdPrompt + "\\command"; try { Windows.WinRegistry.SetValue(Registry.LocalMachine, cmdHere, "", "命令行"); Windows.WinRegistry.SetValue(Registry.LocalMachine, cmdHere, "Icon", "cmd.exe"); Windows.WinRegistry.SetValue(Registry.LocalMachine, cmdHereCommand, "", "\"cmd.exe\""); Windows.WinRegistry.SetValue(Registry.LocalMachine, cmdPrompt, "", "命令行"); Windows.WinRegistry.SetValue(Registry.LocalMachine, cmdPromptCommand, "", "\"cmd.exe\" \"cd %1\""); cmdHere = "SOFTWARE\\Classes\\Directory\\shell\\cmd_here"; cmdHereCommand = cmdHere + "\\command"; Windows.WinRegistry.SetValue(Registry.LocalMachine, cmdHere, "", "命令行"); Windows.WinRegistry.SetValue(Registry.LocalMachine, cmdHere, "Icon", "cmd.exe"); Windows.WinRegistry.SetValue(Registry.LocalMachine, cmdHereCommand, "", "\"cmd.exe\""); VirtualRoot.Happened(new RegCmdHereEvent(true, "windows右键命令行添加成功")); } catch (Exception e) { Logger.ErrorDebugLine(e); VirtualRoot.Happened(new RegCmdHereEvent(false, "windows右键命令行添加失败")); } }); #region 挖矿开始时将无份额内核重启份额计数置0 int shareCount = 0; DateTime shareOn = DateTime.Now; VirtualRoot.On <MineStartedEvent>("挖矿开始后将无份额内核重启份额计数置0,应用超频,启动NoDevFee,启动DevConsole,清理除当前外的Temp/Kernel", LogEnum.DevConsole, action: message => { // 将无份额内核重启份额计数置0 shareCount = 0; shareOn = DateTime.Now; try { if (GpuProfileSet.Instance.IsOverClockEnabled(message.MineContext.MainCoin.GetId())) { VirtualRoot.Execute(new CoinOverClockCommand(message.MineContext.MainCoin.GetId())); } } catch (Exception e) { Logger.ErrorDebugLine(e); } StartNoDevFeeAsync(); }); #endregion #region 每20秒钟检查是否需要重启 VirtualRoot.On <Per20SecondEvent>("每20秒钟阻止windows系统休眠、检查是否需要重启", LogEnum.None, action: message => { // 阻止windows休眠 Windows.Power.PreventWindowsSleep(); #region 重启电脑 try { if (MinerProfile.IsPeriodicRestartComputer) { if ((DateTime.Now - this.CreatedOn).TotalMinutes > 60 * MinerProfile.PeriodicRestartComputerHours + MinerProfile.PeriodicRestartComputerMinutes) { Logger.WarnWriteLine($"每运行{MinerProfile.PeriodicRestartKernelHours}小时{MinerProfile.PeriodicRestartComputerMinutes}分钟重启电脑"); Windows.Power.Restart(); return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(e); } #endregion #region 周期重启内核 try { if (IsMining && MinerProfile.IsPeriodicRestartKernel) { if ((DateTime.Now - CurrentMineContext.CreatedOn).TotalMinutes > 60 * MinerProfile.PeriodicRestartKernelHours + MinerProfile.PeriodicRestartKernelMinutes) { Logger.WarnWriteLine($"每运行{MinerProfile.PeriodicRestartKernelHours}小时{MinerProfile.PeriodicRestartKernelMinutes}分钟重启内核"); RestartMine(); return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(e); } #endregion #region 收益没有增加重启内核 try { if (IsMining && MinerProfile.IsNoShareRestartKernel) { if ((DateTime.Now - shareOn).TotalMinutes > MinerProfile.NoShareRestartKernelMinutes) { if (this.CurrentMineContext.MainCoin != null) { ICoinShare mainCoinShare = this.CoinShareSet.GetOrCreate(this.CurrentMineContext.MainCoin.GetId()); int totalShare = mainCoinShare.TotalShareCount; if ((this.CurrentMineContext is IDualMineContext dualMineContext) && dualMineContext.DualCoin != null) { ICoinShare dualCoinShare = this.CoinShareSet.GetOrCreate(dualMineContext.DualCoin.GetId()); totalShare += dualCoinShare.TotalShareCount; } if (shareCount == totalShare) { Logger.WarnWriteLine($"{MinerProfile.NoShareRestartKernelMinutes}分钟收益没有增加重启内核"); RestartMine(); return; // 退出 } else { shareCount = totalShare; shareOn = DateTime.Now; } }
public void Init(Action callback) { Task.Factory.StartNew(() => { bool isWork = Environment.GetCommandLineArgs().Contains("--work", StringComparer.OrdinalIgnoreCase); if (isWork) { DoInit(isWork, callback); return; } // 如果是Debug模式且不是群控客户端且不是作业则使用本地数据库初始化 if (DevMode.IsDebugMode && !VirtualRoot.IsMinerStudio) { DoInit(isWork: false, callback: callback); return; } Logger.InfoDebugLine("开始下载server.json"); SpecialPath.GetAliyunServerJson((data) => { // 如果server.json未下载成功则不覆写本地server.json if (data != null && data.Length != 0) { Logger.InfoDebugLine("GetAliyunServerJson下载成功"); var serverJson = Encoding.UTF8.GetString(data); if (!string.IsNullOrEmpty(serverJson)) { SpecialPath.WriteServerJsonFile(serverJson); } OfficialServer.GetJsonFileVersionAsync(AssemblyInfo.ServerJsonFileName, (serverJsonFileVersion, minerClientVersion) => { SetServerJsonVersion(serverJsonFileVersion); if (!string.IsNullOrEmpty(minerClientVersion) && minerClientVersion != CurrentVersion.ToString()) { ServerVersion = minerClientVersion; VirtualRoot.Happened(new ServerVersionChangedEvent()); } }); } else { Logger.InfoDebugLine("GetAliyunServerJson下载失败"); } DoInit(isWork, callback); }); #region 发生了用户活动时检查serverJson是否有新版本 VirtualRoot.On <UserActionEvent>("发生了用户活动时检查serverJson是否有新版本", LogEnum.DevConsole, action: message => { OfficialServer.GetJsonFileVersionAsync(AssemblyInfo.ServerJsonFileName, (serverJsonFileVersion, minerClientVersion) => { if (!string.IsNullOrEmpty(minerClientVersion) && minerClientVersion != CurrentVersion.ToString()) { ServerVersion = minerClientVersion; VirtualRoot.Happened(new ServerVersionChangedEvent()); } string localServerJsonFileVersion = GetServerJsonVersion(); if (!string.IsNullOrEmpty(serverJsonFileVersion) && localServerJsonFileVersion != serverJsonFileVersion) { SpecialPath.GetAliyunServerJson((data) => { Write.UserInfo($"server.json配置文件有新版本{localServerJsonFileVersion}->{serverJsonFileVersion}"); string rawJson = Encoding.UTF8.GetString(data); SpecialPath.WriteServerJsonFile(rawJson); SetServerJsonVersion(serverJsonFileVersion); ReInitServerJson(); bool isUseJson = !DevMode.IsDebugMode || VirtualRoot.IsMinerStudio; if (isUseJson) { // 作业模式下界面是禁用的,所以这里的初始化isWork必然是false ContextReInit(isWork: VirtualRoot.IsMinerStudio); Write.UserInfo("刷新完成"); } else { Write.UserInfo("不是使用的server.json,无需刷新"); } }); } else { Write.DevDebug("server.json没有新版本"); } }); }); #endregion }); // 因为这个操作大概需要200毫秒 Task.Factory.StartNew(() => { NVIDIAGpuSet.NvmlInit(); }); }
protected override void OnStartup(StartupEventArgs e) { RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; if (!string.IsNullOrEmpty(CommandLineArgs.Upgrade)) { AppStatic.Upgrade(CommandLineArgs.Upgrade, () => { Environment.Exit(0); }); } else { try { appMutex = new Mutex(true, s_appPipName, out createdNew); } catch (Exception) { createdNew = false; } if (createdNew) { if (!NTMiner.Windows.WMI.IsWmiEnabled) { DialogWindow.ShowDialog(message: "开源矿工无法运行所需的组件,因为本机未开机WMI服务,开源矿工需要使用WMI服务检测windows的内存、显卡等信息,请先手动开启WMI。", title: "提醒", icon: "Icon_Error"); Shutdown(); Environment.Exit(0); } NTMinerOverClockUtil.ExtractResource(); AppStatic.SetIsMinerClient(true); NotiCenterWindowViewModel.IsHotKeyEnabled = true; SplashWindow splashWindow = new SplashWindow(); splashWindow.Show(); NotiCenterWindow.Instance.Show(); NTMinerRoot.Instance.Init(() => { NTMinerRoot.KernelDownloader = new KernelDownloader(); UIThread.Execute(() => { if (!NTMinerRegistry.GetIsNoUi() || !NTMinerRegistry.GetIsAutoStart()) { Views.MainWindow.ShowMainWindow(); } else { NotiCenterWindowViewModel.Instance.Manager.ShowSuccessMessage("已切换为无界面模式运行", "开源矿工"); } System.Drawing.Icon icon = new System.Drawing.Icon(GetResourceStream(new Uri("pack://application:,,,/NTMiner;component/logo.ico")).Stream); AppHelper.NotifyIcon = ExtendedNotifyIcon.Create(icon, "开源矿工", isMinerStudio: false); #region 处理显示主界面命令 VirtualRoot.Window <ShowMainWindowCommand>("处理显示主界面命令", LogEnum.None, action: message => { UIThread.Execute(() => { MainWindow mainWindow = this.MainWindow as MainWindow; if (mainWindow == null) { AppContext.Enable(); Views.MainWindow.ShowMainWindow(); // 使状态栏显示显示最新状态 if (NTMinerRoot.Instance.IsMining) { var coinShare = NTMinerRoot.Instance.CoinShareSet.GetOrCreate(NTMinerRoot.Instance.CurrentMineContext.MainCoin.GetId()); VirtualRoot.Happened(new ShareChangedEvent(coinShare)); if (NTMinerRoot.Instance.CurrentMineContext is IDualMineContext dualMineContext) { coinShare = NTMinerRoot.Instance.CoinShareSet.GetOrCreate(dualMineContext.DualCoin.GetId()); VirtualRoot.Happened(new ShareChangedEvent(coinShare)); } AppContext.Instance.GpuSpeedVms.Refresh(); } } else { mainWindow.ShowThisWindow(message.IsToggle); } }); }); #endregion splashWindow?.Close(); Task.Factory.StartNew(() => { try { HttpServer.Start($"http://localhost:{WebApiConst.MinerClientPort}"); NTMinerRoot.Instance.Start(); } catch (Exception ex) { Logger.ErrorDebugLine(ex.Message, ex); } }); }); }); Link(); } else { try { AppHelper.ShowMainWindow(this, MinerServer.NTMinerAppType.MinerClient); } catch (Exception) { DialogWindow.ShowDialog(message: "另一个NTMiner正在运行,请手动结束正在运行的NTMiner进程后再次尝试。", title: "提醒", icon: "Icon_Error"); Process currentProcess = Process.GetCurrentProcess(); NTMiner.Windows.TaskKill.KillOtherProcess(currentProcess); } } } base.OnStartup(e); }