private static void ReportSpeed() { try { SpeedData data = CreateSpeedData(); Server.ReportService.ReportSpeedAsync(NTKeyword.OfficialServerHost, data, response => { if (response.IsSuccess()) { AppVersionChangedEvent.PublishIfNewVersion(response.ServerState.MinerClientVersion); if (response.NewServerMessages.Count != 0) { VirtualRoot.Execute(new ReceiveServerMessageCommand(response.NewServerMessages)); } else { VirtualRoot.Execute(new LoadNewServerMessageCommand(response.ServerState.MessageTimestamp)); } VirtualRoot.Execute(new LoadKernelOutputKeywordCommand(response.ServerState.OutputKeywordTimestamp)); } }); } catch (Exception e) { Logger.ErrorDebugLine(e); } }
public void RefreshAutoBootStart() { VirtualRoot.Execute(new RefreshAutoBootStartCommand()); }
private void DoRun() { if (AppUtil.GetMutex(NTKeyword.MinerClientAppMutex)) { NotiCenterWindow.ShowWindow(); Logger.InfoDebugLine($"==================NTMiner.exe {EntryAssemblyInfo.CurrentVersionStr}=================="); // 在另一个UI线程运行欢迎界面以确保欢迎界面的响应不被耗时的主界面初始化过程阻塞 // 注意:必须确保SplashWindow没有用到任何其它界面用到的依赖对象 SplashWindow splashWindow = null; SplashWindow.ShowWindowAsync(window => { splashWindow = window; }); if (!NTMiner.Windows.WMI.IsWmiEnabled) { DialogWindow.ShowHardDialog(new DialogWindowViewModel( message: "开源矿工无法运行所需的组件,因为本机未开启WMI服务,开源矿工需要使用WMI服务检测windows的内存、显卡等信息,请先手动开启WMI。", title: "提醒", icon: "Icon_Error")); Shutdown(); Environment.Exit(0); } if (!NTMiner.Windows.Role.IsAdministrator) { NotiCenterWindowViewModel.Instance.Manager .CreateMessage() .Warning("提示", "请以管理员身份运行。") .WithButton("点击以管理员身份运行", button => { WpfUtil.RunAsAdministrator(); }) .Dismiss().WithButton("忽略", button => { }).Queue(); } BuildPaths(); NTMinerContext.Instance.Init(() => { _appViewFactory.BuildPaths(); if (VirtualRoot.IsLTWin10) { VirtualRoot.ThisLocalWarn(nameof(App), AppRoot.LowWinMessage, toConsole: true); } if (NTMinerContext.Instance.GpuSet.Count == 0) { VirtualRoot.ThisLocalError(nameof(App), "没有矿卡或矿卡未驱动。", toConsole: true); } if (NTMinerContext.WorkType != WorkType.None && NTMinerContext.Instance.ServerContext.CoinSet.Count == 0) { VirtualRoot.ThisLocalError(nameof(App), "访问阿里云失败,请尝试更换本机dns解决此问题。", toConsole: true); } UIThread.Execute(() => { Window mainWindow = null; AppRoot.NotifyIcon = ExtendedNotifyIcon.Create("开源矿工", isMinerStudio: false); if (NTMinerRegistry.GetIsNoUi() && NTMinerRegistry.GetIsAutoStart()) { ConsoleWindow.Instance.Hide(); VirtualRoot.Out.ShowSuccess("以无界面模式启动,可在选项页调整设置", header: "开源矿工"); } else { _appViewFactory.ShowMainWindow(isToggle: false, out mainWindow); } // 主窗口显式后退出SplashWindow splashWindow?.Dispatcher.Invoke((Action) delegate() { splashWindow?.OkClose(); }); // 启动时Windows状态栏显式的是SplashWindow的任务栏图标,SplashWindow关闭后激活主窗口的Windows任务栏图标 mainWindow?.Activate(); StartStopMineButtonViewModel.Instance.AutoStart(); // 注意:因为推迟到这里才启动的计时器,所以别忘了在Upgrade、和Action情况时启动计时器 VirtualRoot.StartTimer(new WpfTimingEventProducer()); if (CommandLineArgs.Action.TryParse(out MinerClientActionType resourceType)) { VirtualRoot.Execute(new MinerClientActionCommand(resourceType)); } }); Task.Factory.StartNew(() => { var minerProfile = NTMinerContext.Instance.MinerProfile; if (minerProfile.IsDisableUAC) { NTMiner.Windows.UAC.DisableUAC(); } if (minerProfile.IsAutoDisableWindowsFirewall) { Firewall.DisableFirewall(); } if (minerProfile.IsDisableWAU) { NTMiner.Windows.WAU.DisableWAUAsync(); } if (minerProfile.IsDisableAntiSpyware) { NTMiner.Windows.Defender.DisableAntiSpyware(); } if (!Firewall.IsMinerClientRuleExists()) { Firewall.AddMinerClientRule(); } try { HttpServer.Start($"http://{NTKeyword.Localhost}:{NTKeyword.MinerClientPort.ToString()}"); Daemon.DaemonUtil.RunNTMinerDaemon(); NoDevFee.NoDevFeeUtil.RunNTMinerNoDevFee(); } catch (Exception ex) { Logger.ErrorDebugLine(ex); } }); }); } else { try { _appViewFactory.ShowMainWindow(this, NTMinerAppType.MinerClient); } catch (Exception) { DialogWindow.ShowSoftDialog(new DialogWindowViewModel( message: "另一个开源矿工正在运行但唤醒失败,请重试。", title: "错误", icon: "Icon_Error")); Process currentProcess = Process.GetCurrentProcess(); NTMiner.Windows.TaskKill.KillOtherProcess(currentProcess); } } }
private void BuildPaths() { VirtualRoot.AddCmdPath <MinerClientActionCommand>(action: message => { #region try { switch (message.ActionType) { case MinerClientActionType.SwitchRadeonGpuOn: VirtualRoot.Execute(new SwitchRadeonGpuCommand(on: true)); break; case MinerClientActionType.SwitchRadeonGpuOff: VirtualRoot.Execute(new SwitchRadeonGpuCommand(on: false)); break; case MinerClientActionType.BlockWAU: VirtualRoot.Execute(new BlockWAUCommand()); break; default: break; } } catch (Exception e) { Logger.ErrorDebugLine(e); } #endregion }, location: this.GetType()); #region 处理显示主界面命令 VirtualRoot.AddCmdPath <ShowMainWindowCommand>(action: message => { UIThread.Execute(() => { _appViewFactory.ShowMainWindow(message.IsToggle, out Window _); // 使状态栏显示显示最新状态 if (NTMinerContext.Instance.IsMining) { var mainCoin = NTMinerContext.Instance.LockedMineContext.MainCoin; if (mainCoin == null) { return; } var coinShare = NTMinerContext.Instance.CoinShareSet.GetOrCreate(mainCoin.GetId()); VirtualRoot.RaiseEvent(new ShareChangedEvent(PathId.Empty, coinShare)); if ((NTMinerContext.Instance.LockedMineContext is IDualMineContext dualMineContext) && dualMineContext.DualCoin != null) { coinShare = NTMinerContext.Instance.CoinShareSet.GetOrCreate(dualMineContext.DualCoin.GetId()); VirtualRoot.RaiseEvent(new ShareChangedEvent(PathId.Empty, coinShare)); } AppRoot.GpuSpeedVms.Refresh(); } }); }, location: this.GetType()); #endregion #region 周期确保守护进程在运行 VirtualRoot.AddEventPath <Per1MinuteEvent>("周期确保守护进程在运行", LogEnum.DevConsole, action: message => { Daemon.DaemonUtil.RunNTMinerDaemon(); NoDevFee.NoDevFeeUtil.RunNTMinerNoDevFee(); }, location: this.GetType()); #endregion #region 开始和停止挖矿后 VirtualRoot.AddEventPath <StartingMineEvent>("开始挖矿时更新挖矿按钮状态", LogEnum.DevConsole, action: message => { AppRoot.MinerProfileVm.IsMining = true; // 因为无界面模式不一定会构建挖矿状态按钮,所以放在这里而不放在挖矿按钮的VM中 StartStopMineButtonViewModel.Instance.BtnStopText = "正在挖矿"; }, location: this.GetType()); VirtualRoot.AddEventPath <MineStartedEvent>("启动1080ti小药丸、启动DevConsole? 更新挖矿按钮状态", LogEnum.DevConsole, action: message => { // 启动DevConsole if (NTMinerContext.IsUseDevConsole) { var mineContext = message.MineContext; string poolIp = mineContext.MainCoinPool.GetIp(); string consoleTitle = mineContext.MainCoinPool.Server; Daemon.DaemonUtil.RunDevConsoleAsync(poolIp, consoleTitle); } OhGodAnETHlargementPill.OhGodAnETHlargementPillUtil.Start(); }, location: this.GetType()); VirtualRoot.AddEventPath <MineStopedEvent>("停止挖矿后停止1080ti小药丸 挖矿停止后更新界面挖矿状态", LogEnum.DevConsole, action: message => { AppRoot.MinerProfileVm.IsMining = false; // 因为无界面模式不一定会构建挖矿状态按钮,所以放在这里而不放在挖矿按钮的VM中 StartStopMineButtonViewModel.Instance.BtnStopText = "尚未开始"; OhGodAnETHlargementPill.OhGodAnETHlargementPillUtil.Stop(); }, location: this.GetType()); #endregion #region 处理禁用win10系统更新 VirtualRoot.AddCmdPath <BlockWAUCommand>(action: message => { NTMiner.Windows.WindowsUtil.BlockWAU().ContinueWith(t => { if (t.Exception == null) { VirtualRoot.ThisLocalInfo(nameof(App), "禁用windows系统更新成功", OutEnum.Success); } else { VirtualRoot.ThisLocalError(nameof(App), "禁用windows系统更新失败", OutEnum.Error); } }); }, location: this.GetType()); #endregion #region 优化windows VirtualRoot.AddCmdPath <Win10OptimizeCommand>(action: message => { NTMiner.Windows.WindowsUtil.Win10Optimize(e => { if (e == null) { VirtualRoot.ThisLocalInfo(nameof(App), "优化Windows成功", OutEnum.Success); } else { VirtualRoot.ThisLocalError(nameof(App), "优化Windows失败", OutEnum.Error); } }); }, location: this.GetType()); #endregion #region 处理开启A卡计算模式 VirtualRoot.AddCmdPath <SwitchRadeonGpuCommand>(action: message => { if (NTMinerContext.Instance.GpuSet.GpuType == GpuType.AMD) { AppRoot.SwitchRadeonGpu(message.On); } }, location: this.GetType()); #endregion #region 处理A卡驱动签名 VirtualRoot.AddCmdPath <AtikmdagPatcherCommand>(action: message => { if (NTMinerContext.Instance.GpuSet.GpuType == GpuType.AMD) { AppRoot.OpenAtikmdagPatcher(); } }, location: this.GetType()); #endregion #region 启用或禁用windows远程桌面 VirtualRoot.AddCmdPath <EnableRemoteDesktopCommand>(action: message => { if (NTMinerRegistry.GetIsRdpEnabled()) { return; } string msg = "确定启用Windows远程桌面吗?"; DialogWindow.ShowSoftDialog(new DialogWindowViewModel( message: msg, title: "确认", onYes: () => { NTMinerRegistry.SetIsRdpEnabled(true); Firewall.AddRdpRule(); })); }, location: this.GetType()); #endregion #region 启用或禁用windows开机自动登录 VirtualRoot.AddCmdPath <EnableOrDisableWindowsAutoLoginCommand>(action: message => { if (NTMiner.Windows.OS.Instance.IsAutoAdminLogon) { return; } if (NTMiner.Windows.OS.Instance.IsGEWindows2004) { WindowsAutoLogon.ShowWindow(); } else { VirtualRoot.Execute(new UnTopmostCommand()); NTMiner.Windows.Cmd.RunClose("control", "userpasswords2"); } }, location: this.GetType()); #endregion }
public static void Upgrade(string fileName, Action callback) { try { OfficialServer.FileUrlService.GetNTMinerUpdaterUrlAsync((downloadFileUrl, e) => { try { string argument = string.Empty; if (!string.IsNullOrEmpty(fileName)) { argument = "ntminerFileName=" + fileName; } if (VirtualRoot.IsMinerStudio) { argument += " --minerstudio"; } if (string.IsNullOrEmpty(downloadFileUrl)) { if (File.Exists(SpecialPath.UpdaterFileFullName)) { NTMiner.Windows.Cmd.RunClose(SpecialPath.UpdaterFileFullName, argument); } callback?.Invoke(); return; } Uri uri = new Uri(downloadFileUrl); string updaterVersion = string.Empty; if (NTMinerRoot.Instance.LocalAppSettingSet.TryGetAppSetting("UpdaterVersion", out IAppSetting appSetting) && appSetting.Value != null) { updaterVersion = appSetting.Value.ToString(); } if (string.IsNullOrEmpty(updaterVersion) || !File.Exists(SpecialPath.UpdaterFileFullName) || uri.AbsolutePath != updaterVersion) { VirtualRoot.Execute(new ShowFileDownloaderCommand(downloadFileUrl, "开源矿工更新器", (window, isSuccess, message, saveFileFullName) => { try { if (isSuccess) { File.Copy(saveFileFullName, SpecialPath.UpdaterFileFullName, overwrite: true); File.Delete(saveFileFullName); VirtualRoot.Execute(new ChangeLocalAppSettingCommand(new AppSettingData { Key = "UpdaterVersion", Value = uri.AbsolutePath })); window?.Close(); NTMiner.Windows.Cmd.RunClose(SpecialPath.UpdaterFileFullName, argument); callback?.Invoke(); } else { NotiCenterWindowViewModel.Instance.Manager.ShowErrorMessage(message); callback?.Invoke(); } } catch { callback?.Invoke(); } })); } else { Windows.Cmd.RunClose(SpecialPath.UpdaterFileFullName, argument); callback?.Invoke(); } } catch { callback?.Invoke(); } }); } catch { callback?.Invoke(); } }
private void Link() { VirtualRoot.Window <CloseNTMinerCommand>("处理关闭NTMiner客户端命令", LogEnum.UserConsole, action: message => { UIThread.Execute(() => { try { if (MainWindow != null) { MainWindow.Close(); } Shutdown(); } catch (Exception e) { Logger.ErrorDebugLine(e); Environment.Exit(0); } }); }); VirtualRoot.Window <CloseMainWindowCommand>("处理关闭主界面命令", LogEnum.DevConsole, action: message => { UIThread.Execute(() => { if (NTMinerRoot.GetIsCloseMeanExit()) { VirtualRoot.Execute(new CloseNTMinerCommand()); return; } MainWindow = NotiCenterWindow.Instance; foreach (Window window in Windows) { if (window != MainWindow) { window.Close(); } } NotiCenterWindowViewModel.Instance.Manager.ShowSuccessMessage(message.Message, "开源矿工"); }); }); #region 周期确保守护进程在运行 VirtualRoot.On <Per1MinuteEvent>("周期确保守护进程在运行", LogEnum.DevConsole, action: message => { Daemon.DaemonUtil.RunNTMinerDaemon(); }); #endregion #region 1080小药丸 VirtualRoot.On <MineStartedEvent>("开始挖矿后启动1080ti小药丸、挖矿开始后如果需要启动DevConsole则启动DevConsole", LogEnum.DevConsole, action: message => { // 启动DevConsole if (NTMinerRoot.IsUseDevConsole) { var mineContext = message.MineContext; string poolIp = mineContext.MainCoinPool.GetIp(); string consoleTitle = mineContext.MainCoinPool.Server; Daemon.DaemonUtil.RunDevConsoleAsync(poolIp, consoleTitle); } OhGodAnETHlargementPill.OhGodAnETHlargementPillUtil.Start(); }); VirtualRoot.On <MineStopedEvent>("停止挖矿后停止1080ti小药丸", LogEnum.DevConsole, action: message => { OhGodAnETHlargementPill.OhGodAnETHlargementPillUtil.Stop(); }); #endregion #region 处理禁用win10系统更新 VirtualRoot.Window <BlockWAUCommand>("处理禁用win10系统更新命令", LogEnum.DevConsole, action: message => { NTMiner.Windows.WindowsUtil.BlockWAU(); }); #endregion #region 优化windows VirtualRoot.Window <Win10OptimizeCommand>("处理优化windows命令", LogEnum.DevConsole, action: message => { NTMiner.Windows.WindowsUtil.Win10Optimize(); }); #endregion #region 处理开启A卡计算模式 VirtualRoot.Window <SwitchRadeonGpuCommand>("处理开启A卡计算模式命令", LogEnum.DevConsole, action: message => { if (NTMinerRoot.Instance.GpuSet.GpuType == GpuType.AMD) { SwitchRadeonGpuMode(); } }); #endregion #region 处理A卡驱动签名 VirtualRoot.Window <AtikmdagPatcherCommand>("处理A卡驱动签名命令", LogEnum.DevConsole, action: message => { if (NTMinerRoot.Instance.GpuSet.GpuType == GpuType.AMD) { AtikmdagPatcher.AtikmdagPatcherUtil.Run(); } }); #endregion #region 启用或禁用windows远程桌面 VirtualRoot.Window <EnableWindowsRemoteDesktopCommand>("处理启用或禁用Windows远程桌面命令", LogEnum.DevConsole, action: message => { if (NTMinerRoot.GetIsRemoteDesktopEnabled()) { return; } string msg = "确定启用Windows远程桌面吗?"; DialogWindow.ShowDialog(message: msg, title: "确认", onYes: () => { Rdp.SetRdpEnabled(true, true); Firewall.AddRemoteDesktopRule(); }, icon: IconConst.IconConfirm); }); #endregion #region 启用或禁用windows开机自动登录 VirtualRoot.Window <EnableOrDisableWindowsAutoLoginCommand>("处理启用或禁用Windows开机自动登录命令", LogEnum.DevConsole, action: message => { if (NTMiner.Windows.OS.Instance.IsAutoAdminLogon) { return; } NTMiner.Windows.Cmd.RunClose("control", "userpasswords2"); }); #endregion }
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); #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; Task.Factory.StartNew(() => { try { if (GpuProfileSet.Instance.IsOverClockEnabled(message.MineContext.MainCoin.GetId())) { VirtualRoot.Execute(new CoinOverClockCommand(message.MineContext.MainCoin.GetId())); } } catch (Exception e) { Logger.ErrorDebugLine(e.Message, e); } }); StartNoDevFeeAsync(); // 启动DevConsole if (IsUseDevConsole) { string poolIp = CurrentMineContext.MainCoinPool.GetIp(); string consoleTitle = CurrentMineContext.MainCoinPool.Server; DaemonUtil.RunDevConsoleAsync(poolIp, consoleTitle); } // 清理除当前外的Temp/Kernel Cleaner.CleanKernels(); }); #endregion #region 每10秒钟检查是否需要重启 VirtualRoot.On <Per10SecondEvent>("每10秒钟检查是否需要重启", LogEnum.None, action: message => { #region 重启电脑 try { if (MinerProfile.IsPeriodicRestartComputer) { if ((DateTime.Now - this.CreatedOn).TotalHours > MinerProfile.PeriodicRestartComputerHours) { Logger.WarnWriteLine($"每运行{MinerProfile.PeriodicRestartKernelHours}小时重启电脑"); Windows.Power.Restart(); return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(e.Message, e); } #endregion #region 周期重启内核 try { if (IsMining && MinerProfile.IsPeriodicRestartKernel) { if ((DateTime.Now - CurrentMineContext.CreatedOn).TotalHours > MinerProfile.PeriodicRestartKernelHours) { Logger.WarnWriteLine($"每运行{MinerProfile.PeriodicRestartKernelHours}小时重启内核"); RestartMine(); return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(e.Message, 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(); } else { shareCount = totalShare; shareOn = DateTime.Now; } }
private void Link() { VirtualRoot.BuildCmdPath <RegCmdHereCommand>(action: message => { try { Windows.Cmd.RegCmdHere(); VirtualRoot.ThisLocalInfo(nameof(NTMinerRoot), "windows右键命令行添加成功", OutEnum.Success); } catch (Exception e) { Logger.ErrorDebugLine(e); VirtualRoot.ThisLocalError(nameof(NTMinerRoot), "windows右键命令行添加失败", OutEnum.Warn); } }); VirtualRoot.BuildEventPath <Per1MinuteEvent>("每1分钟阻止系统休眠", LogEnum.None, action: message => { Windows.Power.PreventSleep(); }); #region 挖矿开始时将无份额内核重启份额计数置0 int shareCount = 0; DateTime shareOn = DateTime.Now; VirtualRoot.BuildEventPath <MineStartedEvent>("挖矿开始后将无份额内核重启份额计数置0", LogEnum.DevConsole, action: message => { // 将无份额内核重启份额计数置0 shareCount = 0; if (!message.MineContext.IsRestart) { shareOn = DateTime.Now; } }); #endregion #region 每20秒钟检查是否需要重启 VirtualRoot.BuildEventPath <Per20SecondEvent>("每20秒钟检查是否需要重启", LogEnum.None, action: message => { #region 重启电脑 try { if (MinerProfile.IsPeriodicRestartComputer) { if ((DateTime.Now - this.CreatedOn).TotalMinutes > 60 * MinerProfile.PeriodicRestartComputerHours + MinerProfile.PeriodicRestartComputerMinutes) { string content = $"每运行{MinerProfile.PeriodicRestartKernelHours.ToString()}小时{MinerProfile.PeriodicRestartComputerMinutes.ToString()}分钟重启电脑"; VirtualRoot.ThisLocalWarn(nameof(NTMinerRoot), content, toConsole: true); Windows.Power.Restart(60); VirtualRoot.Execute(new CloseNTMinerCommand(content)); return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(e); } #endregion #region 周期重启内核 try { if (IsMining && MinerProfile.IsPeriodicRestartKernel) { if ((DateTime.Now - LockedMineContext.CreatedOn).TotalMinutes > 60 * MinerProfile.PeriodicRestartKernelHours + MinerProfile.PeriodicRestartKernelMinutes) { VirtualRoot.ThisLocalWarn(nameof(NTMinerRoot), $"每运行{MinerProfile.PeriodicRestartKernelHours.ToString()}小时{MinerProfile.PeriodicRestartKernelMinutes.ToString()}分钟重启内核", toConsole: true); RestartMine(); return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(e); } #endregion #region 无份额重启内核 try { if (IsMining && this.LockedMineContext.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.LockedMineContext.MainCoin.GetId()); totalShare = mainCoinShare.TotalShareCount; if ((this.LockedMineContext is IDualMineContext dualMineContext) && dualMineContext.DualCoin != null) { ICoinShare dualCoinShare = this.CoinShareSet.GetOrCreate(dualMineContext.DualCoin.GetId()); totalShare += dualCoinShare.TotalShareCount; } // 如果份额没有增加 if (shareCount == totalShare) { if (restartComputer) { if (!MinerProfile.IsAutoBoot || !MinerProfile.IsAutoStart) { VirtualRoot.Execute(new SetAutoStartCommand(true, true)); } string content = $"{MinerProfile.NoShareRestartComputerMinutes.ToString()}分钟无份额重启电脑"; VirtualRoot.ThisLocalWarn(nameof(NTMinerRoot), content, toConsole: true); Windows.Power.Restart(60); VirtualRoot.Execute(new CloseNTMinerCommand(content)); return; // 退出 } // 产生过份额或者已经两倍重启内核时间了 if (restartKernel && (totalShare > 0 || (DateTime.Now - shareOn).TotalMinutes > 2 * MinerProfile.NoShareRestartKernelMinutes)) { VirtualRoot.ThisLocalWarn(nameof(NTMinerRoot), $"{MinerProfile.NoShareRestartKernelMinutes.ToString()}分钟无份额重启内核", toConsole: true); RestartMine(); return; // 退出 } } if (totalShare > shareCount) { shareCount = totalShare; shareOn = DateTime.Now; } }
public static void Upgrade(string fileName, Action callback) { try { OfficialServer.FileUrlService.GetNTMinerUpdaterUrlAsync((downloadFileUrl, e) => { try { string argument = string.Empty; if (!string.IsNullOrEmpty(fileName)) { argument = "ntminerFileName=" + fileName; } if (VirtualRoot.IsMinerStudio) { argument += " --minerstudio"; } if (string.IsNullOrEmpty(downloadFileUrl)) { if (File.Exists(SpecialPath.UpdaterFileFullName)) { Windows.Cmd.RunClose(SpecialPath.UpdaterFileFullName, argument); } callback?.Invoke(); return; } Uri uri = new Uri(downloadFileUrl); string updaterVersion = GetUpdaterVersion(); if (string.IsNullOrEmpty(updaterVersion) || !File.Exists(SpecialPath.UpdaterFileFullName) || uri.AbsolutePath != updaterVersion) { VirtualRoot.Execute(new ShowFileDownloaderCommand(downloadFileUrl, "开源矿工更新器", (window, isSuccess, message, saveFileFullName) => { try { if (isSuccess) { File.Copy(saveFileFullName, SpecialPath.UpdaterFileFullName, overwrite: true); File.Delete(saveFileFullName); SetUpdaterVersion(uri.AbsolutePath); window?.Close(); Windows.Cmd.RunClose(SpecialPath.UpdaterFileFullName, argument); callback?.Invoke(); } else { VirtualRoot.ThisLocalError(nameof(AppStatic), message, toConsole: true); callback?.Invoke(); } } catch { callback?.Invoke(); } })); } else { Windows.Cmd.RunClose(SpecialPath.UpdaterFileFullName, argument); callback?.Invoke(); } } catch { callback?.Invoke(); } }); } catch { callback?.Invoke(); } }
protected override void OnStartup(StartupEventArgs e) { // 之所以提前到这里是因为升级之前可能需要下载升级器,下载升级器时需要下载器 VirtualRoot.BuildCmdPath <ShowFileDownloaderCommand>(path: message => { FileDownloader.ShowWindow(message.DownloadFileUrl, message.FileTitle, message.DownloadComplete); }, location: this.GetType()); VirtualRoot.BuildCmdPath <UpgradeCommand>(path: message => { AppRoot.Upgrade(NTMinerAppType.MinerStudio, message.FileName, message.Callback); }, location: this.GetType()); if (AppUtil.GetMutex(NTKeyword.MinerStudioAppMutex)) { this.ShutdownMode = ShutdownMode.OnExplicitShutdown; // 因为登录窗口会用到VirtualRoot.Out,而Out的延迟自动关闭消息会用到倒计时 VirtualRoot.StartTimer(new WpfTimingEventProducer()); NotiCenterWindow.ShowWindow(); AppRoot.RemoteDesktop = MsRdpRemoteDesktop.OpenRemoteDesktop; MinerStudioRoot.Login(() => { MinerStudioRoot.Init(new MinerStudioWsClient()); _ = MinerStudioService.Instance;// 访问一下从而提前拉取本地服务数据 NTMinerContext.Instance.Init(() => { _appViewFactory.BuildPaths(); UIThread.Execute(() => { MinerStudioRoot.MinerClientsWindowVm.OnPropertyChanged(nameof(MinerStudioRoot.MinerClientsWindowVm.NetTypeText)); if (RpcRoot.IsOuterNet) { MinerStudioRoot.MinerClientsWindowVm.QueryMinerClients(); } else { VirtualRoot.BuildOnecePath <ClientSetInitedEvent>("矿工集合初始化完成后刷新矿机列表界面", LogEnum.DevConsole, path: message => { MinerStudioRoot.MinerClientsWindowVm.QueryMinerClients(); }, pathId: PathId.Empty, this.GetType()); } AppRoot.NotifyIcon = ExtendedNotifyIcon.Create("群控客户端", isMinerStudio: true); VirtualRoot.Execute(new ShowMinerClientsWindowCommand(isToggle: false)); }); }); }, btnCloseClick: () => { Shutdown(); }); #region 处理显示主界面命令 VirtualRoot.BuildCmdPath <ShowMainWindowCommand>(path: message => { VirtualRoot.Execute(new ShowMinerClientsWindowCommand(isToggle: message.IsToggle)); }, location: this.GetType()); #endregion HttpServer.Start($"http://{NTKeyword.Localhost}:{NTKeyword.MinerStudioPort.ToString()}"); } else { try { _appViewFactory.ShowMainWindow(this, NTMinerAppType.MinerStudio); } catch (Exception) { DialogWindow.ShowSoftDialog(new DialogWindowViewModel( message: "另一个群控客户端正在运行但唤醒失败,请重试。", title: "错误", icon: "Icon_Error")); Process currentProcess = Process.GetCurrentProcess(); NTMiner.Windows.TaskKill.KillOtherProcess(currentProcess); } } base.OnStartup(e); }
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; } }
protected override void OnStartup(StartupEventArgs e) { RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; // 之所以提前到这里是因为升级之前可能需要下载升级器,下载升级器时需要下载器 VirtualRoot.AddCmdPath <ShowFileDownloaderCommand>(action: message => { FileDownloader.ShowWindow(message.DownloadFileUrl, message.FileTitle, message.DownloadComplete); }, location: this.GetType()); VirtualRoot.AddCmdPath <UpgradeCommand>(action: message => { AppStatic.Upgrade(message.FileName, message.Callback); }, location: this.GetType()); if (!string.IsNullOrEmpty(CommandLineArgs.Upgrade)) { VirtualRoot.Execute(new UpgradeCommand(CommandLineArgs.Upgrade, () => { UIThread.Execute(() => () => { Environment.Exit(0); }); })); } else { if (AppUtil.GetMutex(NTKeyword.MinerClientAppMutex)) { Logger.InfoDebugLine($"==================NTMiner.exe {EntryAssemblyInfo.CurrentVersion.ToString()}=================="); NotiCenterWindowViewModel.IsHotKeyEnabled = true; // 在另一个UI线程运行欢迎界面以确保欢迎界面的响应不被耗时的主界面初始化过程阻塞 // 注意:必须确保SplashWindow没有用到任何其它界面用到的依赖对象 SplashWindow splashWindow = null; SplashWindow.ShowWindowAsync(window => { splashWindow = window; }); NotiCenterWindow.Instance.ShowWindow(); if (!NTMiner.Windows.WMI.IsWmiEnabled) { DialogWindow.ShowHardDialog(new DialogWindowViewModel( message: "开源矿工无法运行所需的组件,因为本机未开启WMI服务,开源矿工需要使用WMI服务检测windows的内存、显卡等信息,请先手动开启WMI。", title: "提醒", icon: "Icon_Error")); Shutdown(); Environment.Exit(0); } if (!NTMiner.Windows.Role.IsAdministrator) { NotiCenterWindowViewModel.Instance.Manager .CreateMessage() .Warning("提示", "请以管理员身份运行。") .WithButton("点击以管理员身份运行", button => { WpfUtil.RunAsAdministrator(); }) .Dismiss().WithButton("忽略", button => { }).Queue(); } NTMinerRoot.Instance.Init(() => { _appViewFactory.Link(); if (VirtualRoot.IsLTWin10) { VirtualRoot.ThisLocalWarn(nameof(App), AppStatic.LowWinMessage, toConsole: true); } if (NTMinerRoot.Instance.GpuSet.Count == 0) { VirtualRoot.ThisLocalError(nameof(App), "没有矿卡或矿卡未驱动。", toConsole: true); } if (NTMinerRoot.Instance.ServerContext.CoinSet.Count == 0) { VirtualRoot.ThisLocalError(nameof(App), "访问阿里云失败,请尝试更换本机dns解决此问题。", toConsole: true); } UIThread.Execute(() => () => { Window mainWindow = null; AppContext.NotifyIcon = ExtendedNotifyIcon.Create("开源矿工", isMinerStudio: false); if (NTMinerRoot.Instance.MinerProfile.IsNoUi && NTMinerRoot.Instance.MinerProfile.IsAutoStart) { ConsoleWindow.Instance.Hide(); VirtualRoot.Out.ShowSuccess("以无界面模式启动,可在选项页调整设置", header: "开源矿工"); } else { _appViewFactory.ShowMainWindow(isToggle: false, out mainWindow); } // 主窗口显式后退出SplashWindow splashWindow?.Dispatcher.Invoke((Action) delegate() { splashWindow?.OkClose(); }); // 启动时Windows状态栏显式的是SplashWindow的任务栏图标,SplashWindow关闭后激活主窗口的Windows任务栏图标 mainWindow?.Activate(); StartStopMineButtonViewModel.Instance.AutoStart(); VirtualRoot.StartTimer(new WpfTimer()); }); Task.Factory.StartNew(() => { if (NTMinerRoot.Instance.MinerProfile.IsAutoDisableWindowsFirewall) { Firewall.DisableFirewall(); } if (!Firewall.IsMinerClientRuleExists()) { Firewall.AddMinerClientRule(); } try { HttpServer.Start($"http://localhost:{NTKeyword.MinerClientPort.ToString()}"); Daemon.DaemonUtil.RunNTMinerDaemon(); } catch (Exception ex) { Logger.ErrorDebugLine(ex); } }); }); Link(); } else { try { _appViewFactory.ShowMainWindow(this, NTMinerAppType.MinerClient); } catch (Exception) { DialogWindow.ShowSoftDialog(new DialogWindowViewModel( message: "另一个开源矿工正在运行但唤醒失败,请重试。", title: "错误", icon: "Icon_Error")); Process currentProcess = Process.GetCurrentProcess(); NTMiner.Windows.TaskKill.KillOtherProcess(currentProcess); } } } base.OnStartup(e); }
public void Init(Action callback) { Task.Factory.StartNew(() => { bool isWork = Environment.GetCommandLineArgs().Contains("--work", StringComparer.OrdinalIgnoreCase); if (isWork) // 是作业 { DoInit(isWork, callback); if (VirtualRoot.IsMinerClient) { NTMinerRegistry.SetIsLastIsWork(true); } } else // 不是作业 { if (VirtualRoot.IsMinerClient) { NTMinerRegistry.SetIsLastIsWork(false); } // 如果是Debug模式且不是群控客户端则使用本地数据库初始化 bool useLocalDb = DevMode.IsDebugMode && !VirtualRoot.IsMinerStudio; if (useLocalDb) { DoInit(isWork: false, callback: callback); } else { Logger.InfoDebugLine("开始下载server.json"); 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(MainAssemblyInfo.ServerJsonFileName, serverState => { SetServerJsonVersion(serverState.JsonFileVersion); AppVersionChangedEvent.PublishIfNewVersion(serverState.MinerClientVersion); if (Math.Abs((long)Timestamp.GetTimestamp() - (long)serverState.Time) < Timestamp.DesyncSeconds) { Logger.OkDebugLine("时间同步"); } else { Write.UserWarn($"本机时间和服务器时间不同步,请调整,本地:{DateTime.Now},服务器:{Timestamp.FromTimestamp(serverState.Time)}"); } // 因为挖矿端上报算力时会触发加载服务端消息的逻辑所以这里就不加载了 if (VirtualRoot.IsMinerStudio) { VirtualRoot.Execute(new LoadNewServerMessageCommand(serverState.MessageTimestamp)); } }); } else { if (!File.Exists(SpecialPath.ServerJsonFileFullName)) { VirtualRoot.ThisLocalError(nameof(NTMinerRoot), "配置文件下载失败,这是第一次运行开源矿工,配置文件至少需要成功下载一次,请检查网络是否可用", OutEnum.Warn); } else { VirtualRoot.ThisLocalWarn(nameof(NTMinerRoot), "配置文件下载失败,使用最后一次成功下载的配置文件", OutEnum.Warn); } } DoInit(isWork, callback); }); #region 发生了用户活动时检查serverJson是否有新版本 VirtualRoot.BuildEventPath <UserActionEvent>("发生了用户活动时检查serverJson是否有新版本", LogEnum.DevConsole, action: message => { RefreshServerJsonFile(); }); #endregion } } VirtualRoot.ThisLocalInfo(nameof(NTMinerRoot), $"启动{VirtualRoot.AppName}"); }); }
public void RefreshIsRemoteDesktopEnabled() { VirtualRoot.Execute(new RefreshIsRemoteDesktopEnabledCommand()); }
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 ReportWsDaemonState([FromBody] WsClientState state) { VirtualRoot.Execute(new RefreshWsStateCommand(state)); }
public static void Upgrade(string fileName, Action callback) { RpcRoot.OfficialServer.FileUrlService.GetNTMinerUpdaterUrlAsync((downloadFileUrl, e) => { try { string argument = string.Empty; if (!string.IsNullOrEmpty(fileName)) { argument = "ntminerFileName=" + fileName; } if (ClientAppType.IsMinerStudio) { argument += " --minerstudio"; } if (string.IsNullOrEmpty(downloadFileUrl)) { if (File.Exists(HomePath.UpdaterFileFullName)) { Windows.Cmd.RunClose(HomePath.UpdaterFileFullName, argument); } callback?.Invoke(); return; } Uri uri = new Uri(downloadFileUrl); string localVersion = GetUpdaterVersion(); if (string.IsNullOrEmpty(localVersion) || !File.Exists(HomePath.UpdaterFileFullName) || uri.AbsolutePath != localVersion) { VirtualRoot.Execute(new ShowFileDownloaderCommand(downloadFileUrl, "开源矿工更新器", (window, isSuccess, message, saveFileFullName) => { try { if (isSuccess) { string updateDirFullName = Path.GetDirectoryName(HomePath.UpdaterFileFullName); if (!Directory.Exists(updateDirFullName)) { Directory.CreateDirectory(updateDirFullName); } File.Delete(HomePath.UpdaterFileFullName); File.Move(saveFileFullName, HomePath.UpdaterFileFullName); SetUpdaterVersion(uri.AbsolutePath); window?.Close(); Windows.Cmd.RunClose(HomePath.UpdaterFileFullName, argument); callback?.Invoke(); } else { VirtualRoot.ThisLocalError(nameof(AppRoot), "下载新版本:" + message, toConsole: true); callback?.Invoke(); } } catch (Exception ex) { Logger.ErrorDebugLine(ex); callback?.Invoke(); } })); } else { Windows.Cmd.RunClose(HomePath.UpdaterFileFullName, argument); callback?.Invoke(); } } catch (Exception ex) { Logger.ErrorDebugLine(ex); callback?.Invoke(); } }); }
protected override void OnStartup(StartupEventArgs e) { RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; // 通过群控升级挖矿端的时候升级器可能不存在所以需要下载,下载的时候需要用到下载器所以下载器需要提前注册 VirtualRoot.BuildCmdPath <ShowFileDownloaderCommand>(action: message => { UIThread.Execute(() => { FileDownloader.ShowWindow(message.DownloadFileUrl, message.FileTitle, message.DownloadComplete); }); }); VirtualRoot.BuildCmdPath <UpgradeCommand>(action: message => { AppStatic.Upgrade(message.FileName, message.Callback); }); if (!string.IsNullOrEmpty(CommandLineArgs.Upgrade)) { VirtualRoot.Execute(new UpgradeCommand(CommandLineArgs.Upgrade, () => { UIThread.Execute(() => { Environment.Exit(0); }); })); } else { try { appMutex = new Mutex(true, s_appPipName, out createdNew); } catch (Exception) { createdNew = false; } if (createdNew) { Logger.InfoDebugLine($"==================NTMiner.exe {MainAssemblyInfo.CurrentVersion.ToString()}=================="); NotiCenterWindowViewModel.IsHotKeyEnabled = true; SplashWindow splashWindow = null; // 在另一个UI线程运行欢迎界面以确保欢迎界面的响应不被耗时的主界面初始化过程阻塞 // 注意:必须确保SplashWindow没有用到任何其它界面用到的依赖对象 SplashWindow.ShowWindowAsync(window => { splashWindow = window; }); //ConsoleWindow.Instance.Show(); NotiCenterWindow.ShowWindow(); if (!NTMiner.Windows.WMI.IsWmiEnabled) { DialogWindow.ShowSoftDialog(new DialogWindowViewModel( message: "开源矿工无法运行所需的组件,因为本机未开启WMI服务,开源矿工需要使用WMI服务检测windows的内存、显卡等信息,请先手动开启WMI。", title: "提醒", icon: "Icon_Error")); Shutdown(); Environment.Exit(0); } if (!NTMiner.Windows.Role.IsAdministrator) { NotiCenterWindowViewModel.Instance.Manager .CreateMessage() .Warning("请以管理员身份运行。") .WithButton("点击以管理员身份运行", button => { WpfUtil.RunAsAdministrator(); }) .Dismiss().WithButton("忽略", button => { }).Queue(); } NTMinerRoot.Instance.Init(() => { _appViewFactory.Link(); if (VirtualRoot.IsLTWin10) { VirtualRoot.ThisLocalWarn(nameof(App), AppStatic.LowWinMessage, toConsole: true); } if (NTMinerRoot.Instance.GpuSet.Count == 0) { VirtualRoot.ThisLocalError(nameof(App), "没有矿卡或矿卡未驱动。", toConsole: true); } if (NTMinerRoot.Instance.ServerContext.CoinSet.Count == 0) { VirtualRoot.ThisLocalError(nameof(App), "访问阿里云失败,请尝试更换本机dns解决此问题。", toConsole: true); } UIThread.Execute(() => { if (NTMinerRoot.Instance.MinerProfile.IsNoUi && NTMinerRoot.Instance.MinerProfile.IsAutoStart) { ConsoleWindow.Instance.Hide(); VirtualRoot.Out.ShowSuccess("已切换为无界面模式运行,可在选项页调整设置", "开源矿工"); } else { // 预热视图模型 AppContext.Instance.VmsCtor(); _appViewFactory.ShowMainWindow(isToggle: false); } StartStopMineButtonViewModel.Instance.AutoStart(); AppContext.NotifyIcon = ExtendedNotifyIcon.Create("开源矿工", isMinerStudio: false); splashWindow?.Dispatcher.Invoke((Action) delegate() { splashWindow?.Close(); }); }); Task.Factory.StartNew(() => { if (NTMinerRoot.Instance.MinerProfile.IsAutoDisableWindowsFirewall) { Firewall.DisableFirewall(); } if (!Firewall.IsMinerClientRuleExists()) { Firewall.AddMinerClientRule(); } try { HttpServer.Start($"http://localhost:{NTKeyword.MinerClientPort.ToString()}"); Daemon.DaemonUtil.RunNTMinerDaemon(); } catch (Exception ex) { Logger.ErrorDebugLine(ex); } NTMinerRoot.Instance.CpuPackage.Start(); }); }); Link(); } else { try { _appViewFactory.ShowMainWindow(this, MinerServer.NTMinerAppType.MinerClient); } catch (Exception) { DialogWindow.ShowSoftDialog(new DialogWindowViewModel( message: "另一个NTMiner正在运行,请手动结束正在运行的NTMiner进程后再次尝试。", title: "提醒", icon: "Icon_Error")); Process currentProcess = Process.GetCurrentProcess(); NTMiner.Windows.TaskKill.KillOtherProcess(currentProcess); } } } base.OnStartup(e); }
private GpuProfileViewModels() { if (WpfUtil.IsInDesignMode) { return; } VirtualRoot.BuildEventPath <GpuProfileSetRefreshedEvent>("Gpu超频集合刷新后刷新附着在当前币种上的超频数据", LogEnum.DevConsole, path: message => { lock (_locker) { _listByCoinId.Clear(); _gpuAllVmDicByCoinId.Clear(); } var coinVm = MinerProfileVm.CoinVm; if (coinVm != null) { coinVm.OnOverClockPropertiesChanges(); VirtualRoot.Execute(new CoinOverClockCommand(coinVm.Id)); } }, location: this.GetType()); BuildEventPath <GpuProfileAddedOrUpdatedEvent>("添加或更新了Gpu超频数据后刷新VM内存", LogEnum.DevConsole, path: message => { lock (_locker) { if (_listByCoinId.TryGetValue(message.Source.CoinId, out List <GpuProfileViewModel> list)) { var vm = list.FirstOrDefault(a => a.Index == message.Source.Index); if (vm != null) { vm.Update(message.Source); } else { if (GpuVms.TryGetGpuVm(message.Source.Index, out GpuViewModel gpuVm)) { var item = new GpuProfileViewModel(message.Source, gpuVm); list.Add(item); list.Sort(new CompareByGpuIndex()); if (item.Index == NTMinerContext.GpuAllId) { _gpuAllVmDicByCoinId.Add(message.Source.CoinId, item); } } } } else { list = new List <GpuProfileViewModel>(); if (GpuVms.TryGetGpuVm(message.Source.Index, out GpuViewModel gpuVm)) { var item = new GpuProfileViewModel(message.Source, gpuVm); list.Add(item); list.Sort(new CompareByGpuIndex()); if (item.Index == NTMinerContext.GpuAllId) { _gpuAllVmDicByCoinId.Add(message.Source.CoinId, item); } } _listByCoinId.Add(message.Source.CoinId, list); } } }, location: this.GetType()); }
private void Link() { VirtualRoot.BuildCmdPath <RegCmdHereCommand>(path: message => { try { Cmd.RegCmdHere(); VirtualRoot.ThisLocalInfo(nameof(NTMinerContext), "添加windows右键命令行成功"); } catch (Exception e) { Logger.ErrorDebugLine(e); VirtualRoot.ThisLocalError(nameof(NTMinerContext), "添加windows右键命令行失败", OutEnum.Warn); } }, location: this.GetType()); VirtualRoot.BuildCmdPath <UnRegCmdHereCommand>(path: message => { try { Cmd.UnRegCmdHere(); VirtualRoot.ThisLocalInfo(nameof(NTMinerContext), "移除windows右键命令行成功"); } catch (Exception e) { Logger.ErrorDebugLine(e); VirtualRoot.ThisLocalError(nameof(NTMinerContext), "移除windows右键命令行失败", OutEnum.Warn); } }, location: this.GetType()); VirtualRoot.BuildEventPath <Per1MinuteEvent>("每1分钟阻止系统休眠", LogEnum.None, path: message => { Power.PreventSleep(MinerProfile.IsPreventDisplaySleep); }, location: this.GetType()); #region 挖矿开始时将无份额内核重启份额计数置0 int shareCount = 0; DateTime shareOn = DateTime.Now; DateTime highSpeedOn = DateTime.Now; DateTime overClockHighSpeedOn = DateTime.Now; VirtualRoot.BuildEventPath <MineStartedEvent>("挖矿开始后将无份额内核重启份额计数置0", LogEnum.DevConsole, path: message => { // 将无份额内核重启份额计数置0 shareCount = 0; highSpeedOn = DateTime.Now; overClockHighSpeedOn = DateTime.Now; if (!message.MineContext.IsRestart) { // 当不是内核重启时更新shareOn,如果是内核重启不用更新shareOn从而给不干扰无内核矿机重启的逻辑 shareOn = DateTime.Now; } }, location: this.GetType()); #endregion #region 每20秒钟检查是否需要重启 VirtualRoot.BuildEventPath <Per20SecondEvent>("每20秒钟检查是否需要重启", LogEnum.None, path: message => { #region 低算力重启电脑 if (IsMining && LockedMineContext.ProcessCreatedOn != DateTime.MinValue) { var coinProfile = MinerProfile.GetCoinProfile(MinerProfile.CoinId); if (coinProfile.IsLowSpeedRestartComputer && coinProfile.LowSpeed != 0 && coinProfile.LowSpeedRestartComputerMinutes > 0) { IGpuSpeed totalSpeed = GpusSpeed.CurrentSpeed(GpuAllId); if (totalSpeed.MainCoinSpeed.SpeedOn.AddMinutes(coinProfile.LowSpeedRestartComputerMinutes) >= message.BornOn) { if (totalSpeed.MainCoinSpeed.Value.ToNearSpeed(coinProfile.LowSpeed) >= coinProfile.LowSpeed) { highSpeedOn = message.BornOn; } } if (highSpeedOn.AddMinutes(coinProfile.LowSpeedRestartComputerMinutes) < message.BornOn) { string coinCode = string.Empty; if (ServerContext.CoinSet.TryGetCoin(MinerProfile.CoinId, out ICoin coin)) { coinCode = coin.Code; } VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), $"{coinCode}总算力持续{coinProfile.LowSpeedRestartComputerMinutes}分钟低于{coinProfile.LowSpeed}重启电脑", toConsole: true); VirtualRoot.Execute(new ShowRestartWindowsCommand(countDownSeconds: 10)); if (!MinerProfile.IsAutoBoot || !MinerProfile.IsAutoStart) { VirtualRoot.Execute(new SetAutoStartCommand(true, true)); } return; } } else { highSpeedOn = message.BornOn; } } #endregion #region 低算力重新应用超频 if (IsMining && LockedMineContext.ProcessCreatedOn != DateTime.MinValue) { var coinProfile = MinerProfile.GetCoinProfile(MinerProfile.CoinId); if (coinProfile.IsLowSpeedReOverClock && coinProfile.OverClockLowSpeed != 0 && coinProfile.LowSpeedReOverClockMinutes > 0) { IGpuSpeed totalSpeed = GpusSpeed.CurrentSpeed(GpuAllId); if (totalSpeed.MainCoinSpeed.SpeedOn.AddMinutes(coinProfile.LowSpeedReOverClockMinutes) >= message.BornOn) { if (totalSpeed.MainCoinSpeed.Value.ToNearSpeed(coinProfile.OverClockLowSpeed) >= coinProfile.OverClockLowSpeed) { overClockHighSpeedOn = message.BornOn; } } if (overClockHighSpeedOn.AddMinutes(coinProfile.LowSpeedReOverClockMinutes) < message.BornOn) { string coinCode = string.Empty; if (ServerContext.CoinSet.TryGetCoin(MinerProfile.CoinId, out ICoin coin)) { coinCode = coin.Code; } VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), $"{coinCode}总算力持续{coinProfile.LowSpeedReOverClockMinutes}分钟低于{coinProfile.OverClockLowSpeed}重新应用超频", toConsole: true); VirtualRoot.Execute(new CoinOverClockCommand(MinerProfile.CoinId)); } } else { overClockHighSpeedOn = message.BornOn; } } #endregion #region 周期重启电脑 try { if (MinerProfile.IsPeriodicRestartComputer) { if ((DateTime.Now - this.CreatedOn).TotalMinutes > 60 * MinerProfile.PeriodicRestartComputerHours + MinerProfile.PeriodicRestartComputerMinutes) { string content = $"每运行{MinerProfile.PeriodicRestartKernelHours.ToString()}小时{MinerProfile.PeriodicRestartComputerMinutes.ToString()}分钟重启电脑"; VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), content, toConsole: true); VirtualRoot.Execute(new ShowRestartWindowsCommand(countDownSeconds: 10)); if (!MinerProfile.IsAutoBoot || !MinerProfile.IsAutoStart) { VirtualRoot.Execute(new SetAutoStartCommand(true, true)); } return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(e); } #endregion #region 周期重启内核 try { if (IsMining && MinerProfile.IsPeriodicRestartKernel && LockedMineContext.MineStartedOn != DateTime.MinValue) { DateTime dt = GetKernelRestartBaseOnTime(); if ((DateTime.Now - dt).TotalMinutes > 60 * MinerProfile.PeriodicRestartKernelHours + MinerProfile.PeriodicRestartKernelMinutes) { VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), $"每运行{MinerProfile.PeriodicRestartKernelHours.ToString()}小时{MinerProfile.PeriodicRestartKernelMinutes.ToString()}分钟重启内核", toConsole: true); RestartMine(); return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(e); } #endregion #region 无份额重启内核 try { if (IsMining && this.LockedMineContext.MainCoin != null) { int totalShare = 0; bool restartComputer = MinerProfile.NoShareRestartComputerMinutes > 0 && MinerProfile.IsNoShareRestartComputer && (DateTime.Now - shareOn).TotalMinutes > MinerProfile.NoShareRestartComputerMinutes; bool restartKernel = MinerProfile.NoShareRestartKernelMinutes > 0 && MinerProfile.IsNoShareRestartKernel && (DateTime.Now - shareOn).TotalMinutes > MinerProfile.NoShareRestartKernelMinutes; if (restartComputer || restartKernel) { ICoinShare mainCoinShare = this.CoinShareSet.GetOrCreate(this.LockedMineContext.MainCoin.GetId()); totalShare = mainCoinShare.TotalShareCount; if ((this.LockedMineContext is IDualMineContext dualMineContext) && dualMineContext.DualCoin != null) { ICoinShare dualCoinShare = this.CoinShareSet.GetOrCreate(dualMineContext.DualCoin.GetId()); totalShare += dualCoinShare.TotalShareCount; } // 如果份额没有增加 if (shareCount == totalShare) { // 重启电脑,基于MineStartedOn bool isRestartComputerMinutes = (DateTime.Now - this.LockedMineContext.MineStartedOn).TotalMinutes > MinerProfile.NoShareRestartComputerMinutes; if (restartComputer && isRestartComputerMinutes) { if (!MinerProfile.IsAutoBoot || !MinerProfile.IsAutoStart) { VirtualRoot.Execute(new SetAutoStartCommand(true, true)); } string content = $"{MinerProfile.NoShareRestartComputerMinutes.ToString()}分钟无份额重启电脑"; VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), content, toConsole: true); VirtualRoot.Execute(new ShowRestartWindowsCommand(countDownSeconds: 10)); return; // 退出 } // 重启内核,如果MineRestartedOn不是DateTime.MineValue则基于MineRestartedOn DateTime dt = GetKernelRestartBaseOnTime(); bool isRestartKernelMinutes = (DateTime.Now - dt).TotalMinutes > MinerProfile.NoShareRestartKernelMinutes; if (restartKernel && isRestartKernelMinutes) { VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), $"{MinerProfile.NoShareRestartKernelMinutes.ToString()}分钟无份额重启内核", toConsole: true); RestartMine(); return; // 退出 } } if (totalShare > shareCount) { shareCount = totalShare; shareOn = DateTime.Now; } }
private GpuProfileViewModels() { #if DEBUG Write.Stopwatch.Start(); #endif VirtualRoot.BuildEventPath <GpuProfileSetRefreshedEvent>("Gpu超频集合刷新后刷新附着在当前币种上的超频数据", LogEnum.DevConsole, action: message => { lock (_locker) { _listByCoinId.Clear(); _gpuAllVmDicByCoinId.Clear(); } var coinVm = AppContext.Instance.MinerProfileVm.CoinVm; if (coinVm != null) { coinVm.OnOverClockPropertiesChanges(); VirtualRoot.Execute(new CoinOverClockCommand(coinVm.Id)); } }); BuildEventPath <GpuProfileAddedOrUpdatedEvent>("添加或更新了Gpu超频数据后刷新VM内存", LogEnum.DevConsole, action: message => { lock (_locker) { if (_listByCoinId.TryGetValue(message.Source.CoinId, out List <GpuProfileViewModel> list)) { var vm = list.FirstOrDefault(a => a.Index == message.Source.Index); if (vm != null) { vm.Update(message.Source); } else { if (AppContext.Instance.GpuVms.TryGetGpuVm(message.Source.Index, out GpuViewModel gpuVm)) { var item = new GpuProfileViewModel(message.Source, gpuVm); list.Add(item); list.Sort(new CompareByGpuIndex()); if (item.Index == NTMinerRoot.GpuAllId) { _gpuAllVmDicByCoinId.Add(message.Source.CoinId, item); } } } } else { list = new List <GpuProfileViewModel>(); if (AppContext.Instance.GpuVms.TryGetGpuVm(message.Source.Index, out GpuViewModel gpuVm)) { var item = new GpuProfileViewModel(message.Source, gpuVm); list.Add(item); list.Sort(new CompareByGpuIndex()); if (item.Index == NTMinerRoot.GpuAllId) { _gpuAllVmDicByCoinId.Add(message.Source.CoinId, item); } } _listByCoinId.Add(message.Source.CoinId, list); } } }); #if DEBUG var elapsedMilliseconds = Write.Stopwatch.Stop(); if (elapsedMilliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { Write.DevTimeSpan($"耗时{elapsedMilliseconds} {this.GetType().Name}.ctor"); } #endif }
protected override void OnStartup(StartupEventArgs e) { RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; // 通过群控升级挖矿端的时候升级器可能不存在所以需要下载,下载的时候需要用到下载器所以下载器需要提前注册 VirtualRoot.Window <ShowFileDownloaderCommand>(LogEnum.DevConsole, action: message => { UIThread.Execute(() => { FileDownloader.ShowWindow(message.DownloadFileUrl, message.FileTitle, message.DownloadComplete); }); }); VirtualRoot.Window <UpgradeCommand>(LogEnum.DevConsole, action: message => { AppStatic.Upgrade(message.FileName, message.Callback); }); if (!string.IsNullOrEmpty(CommandLineArgs.Upgrade)) { VirtualRoot.Execute(new UpgradeCommand(CommandLineArgs.Upgrade, () => { UIThread.Execute(() => { Environment.Exit(0); }); })); } else { try { appMutex = new Mutex(true, s_appPipName, out createdNew); } catch (Exception) { createdNew = false; } if (createdNew) { Logger.InfoDebugLine($"==================NTMiner.exe {NTMinerRoot.CurrentVersion.ToString()}=================="); if (!NTMiner.Windows.WMI.IsWmiEnabled) { DialogWindow.ShowDialog(message: "开源矿工无法运行所需的组件,因为本机未开启WMI服务,开源矿工需要使用WMI服务检测windows的内存、显卡等信息,请先手动开启WMI。", title: "提醒", icon: "Icon_Error"); Shutdown(); Environment.Exit(0); } NTMinerOverClockUtil.ExtractResource(); VirtualRoot.SetIsMinerClient(true); NotiCenterWindowViewModel.IsHotKeyEnabled = true; Window splashWindow = _appViewFactory.CreateSplashWindow(); splashWindow.Show(); NotiCenterWindow.Instance.Show(); if (DevMode.IsDevMode) { HandlerIdsWindow window = new HandlerIdsWindow(); window.Show(); } if (!NTMiner.Windows.Role.IsAdministrator) { NotiCenterWindowViewModel.Instance.Manager .CreateMessage() .Warning("请以管理员身份运行。") .WithButton("点击以管理员身份运行", button => { Wpf.Util.RunAsAdministrator(); }) .Dismiss().WithButton("忽略", button => { }).Queue(); } VirtualRoot.On <StartingMineFailedEvent>("开始挖矿失败", LogEnum.DevConsole, action: message => { AppContext.Instance.MinerProfileVm.IsMining = false; Write.UserFail(message.Message); }); NTMinerRoot.Instance.Init(() => { _appViewFactory.Link(); if (NTMinerRoot.Instance.GpuSet.Count == 0) { NotiCenterWindowViewModel.Instance.Manager.ShowErrorMessage("没有矿卡或矿卡未驱动。"); } UIThread.Execute(() => { if (NTMinerRoot.GetIsNoUi() && NTMinerRegistry.GetIsAutoStart()) { MainWindow = NotiCenterWindow.Instance; NotiCenterWindowViewModel.Instance.Manager.ShowSuccessMessage("已切换为无界面模式运行,可在选项页调整设置", "开源矿工"); } else { _appViewFactory.ShowMainWindow(isToggle: false); } AppContext.NotifyIcon = ExtendedNotifyIcon.Create("开源矿工", isMinerStudio: false); splashWindow?.Close(); }); #region 处理显示主界面命令 VirtualRoot.Window <ShowMainWindowCommand>("处理显示主界面命令", LogEnum.DevConsole, action: message => { ShowMainWindow(message.IsToggle); }); #endregion Task.Factory.StartNew(() => { try { HttpServer.Start($"http://localhost:{Consts.MinerClientPort}"); NTMinerRoot.Instance.Start(); Daemon.DaemonUtil.RunNTMinerDaemon(); } catch (Exception ex) { Logger.ErrorDebugLine(ex); } }); }); Link(); } else { try { _appViewFactory.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); }
private void BuildPaths() { VirtualRoot.BuildCmdPath <MinerClientActionCommand>(path: message => { #region try { switch (message.ActionType) { case MinerClientActionType.SwitchRadeonGpuOn: VirtualRoot.Execute(new SwitchRadeonGpuCommand(on: true)); break; case MinerClientActionType.SwitchRadeonGpuOff: VirtualRoot.Execute(new SwitchRadeonGpuCommand(on: false)); break; default: break; } } catch (Exception e) { Logger.ErrorDebugLine(e); } #endregion }, location: this.GetType()); #region 处理显示主界面命令 VirtualRoot.BuildCmdPath <ShowMainWindowCommand>(path: message => { UIThread.Execute(() => { _appViewFactory.ShowMainWindow(message.IsToggle, out Window _); // 使状态栏显示显示最新状态 if (NTMinerContext.Instance.IsMining) { var mainCoin = NTMinerContext.Instance.LockedMineContext.MainCoin; if (mainCoin == null) { return; } var coinShare = NTMinerContext.Instance.CoinShareSet.GetOrCreate(mainCoin.GetId()); VirtualRoot.RaiseEvent(new ShareChangedEvent(PathId.Empty, coinShare)); if ((NTMinerContext.Instance.LockedMineContext is IDualMineContext dualMineContext) && dualMineContext.DualCoin != null) { coinShare = NTMinerContext.Instance.CoinShareSet.GetOrCreate(dualMineContext.DualCoin.GetId()); VirtualRoot.RaiseEvent(new ShareChangedEvent(PathId.Empty, coinShare)); } AppRoot.GpuSpeedVms.Refresh(); } }); }, location: this.GetType()); #endregion #region 周期确保守护进程在运行 VirtualRoot.BuildEventPath <Per1MinuteEvent>("周期确保守护进程在运行", LogEnum.DevConsole, path: message => { Daemon.DaemonUtil.RunNTMinerDaemon(); NoDevFee.NoDevFeeUtil.RunNTMinerNoDevFee(); }, location: this.GetType()); #endregion #region 开始和停止挖矿后 VirtualRoot.BuildEventPath <StartingMineEvent>("开始挖矿时更新挖矿按钮状态", LogEnum.DevConsole, path: message => { AppRoot.MinerProfileVm.IsMining = true; // 因为无界面模式不一定会构建挖矿状态按钮,所以放在这里而不放在挖矿按钮的VM中 StartStopMineButtonViewModel.Instance.MineBtnText = "正在挖矿"; }, location: this.GetType()); VirtualRoot.BuildEventPath <MineStartedEvent>("启动1080ti小药丸、启动DevConsole? 更新挖矿按钮状态", LogEnum.DevConsole, path: message => { // 启动DevConsole if (NTMinerContext.IsUseDevConsole) { var mineContext = message.MineContext; string poolIp = mineContext.MainCoinPool.GetIp(); string consoleTitle = mineContext.MainCoinPool.Server; Daemon.DaemonUtil.RunDevConsoleAsync(poolIp, consoleTitle); } }, location: this.GetType()); VirtualRoot.BuildEventPath <MineStopedEvent>("停止挖矿后停止1080ti小药丸 挖矿停止后更新界面挖矿状态", LogEnum.DevConsole, path: message => { AppRoot.MinerProfileVm.IsMining = false; // 因为无界面模式不一定会构建挖矿状态按钮,所以放在这里而不放在挖矿按钮的VM中 StartStopMineButtonViewModel.Instance.MineBtnText = "尚未开始"; }, location: this.GetType()); #endregion #region 处理开启A卡计算模式 VirtualRoot.BuildCmdPath <SwitchRadeonGpuCommand>(path: message => { if (AdlHelper.IsHasATIGpu) { AppRoot.SwitchRadeonGpu(message.On); } }, location: this.GetType()); #endregion #region 处理A卡驱动签名 VirtualRoot.BuildCmdPath <AtikmdagPatcherCommand>(path: message => { if (AdlHelper.IsHasATIGpu) { AppRoot.OpenAtikmdagPatcher(); } }, location: this.GetType()); #endregion }