private void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e) { VirtualRoot.ThisLocalInfo(nameof(NTMinerRoot), $"Windows SessionSwitch, Reason:{e.Reason}"); }
private SysDicItemViewModels() { #if DEBUG VirtualRoot.Stopwatch.Restart(); #endif VirtualRoot.On <ServerContextReInitedEvent>("ServerContext刷新后刷新VM内存", LogEnum.DevConsole, action: message => { _dicById.Clear(); Init(); }); VirtualRoot.On <ServerContextVmsReInitedEvent>("ServerContext的VM集刷新后刷新视图界面", LogEnum.DevConsole, action: message => { OnPropertyChangeds(); }); On <SysDicItemAddedEvent>("添加了系统字典项后调整VM内存", LogEnum.DevConsole, action: (message) => { if (!_dicById.ContainsKey(message.Source.GetId())) { _dicById.Add(message.Source.GetId(), new SysDicItemViewModel(message.Source)); OnPropertyChangeds(); SysDicViewModel sysDicVm; if (AppContext.Instance.SysDicVms.TryGetSysDicVm(message.Source.DicId, out sysDicVm)) { sysDicVm.OnPropertyChanged(nameof(sysDicVm.SysDicItems)); sysDicVm.OnPropertyChanged(nameof(sysDicVm.SysDicItemsSelect)); } } }); On <SysDicItemUpdatedEvent>("更新了系统字典项后调整VM内存", LogEnum.DevConsole, action: (message) => { if (_dicById.ContainsKey(message.Source.GetId())) { SysDicItemViewModel entity = _dicById[message.Source.GetId()]; int sortNumber = entity.SortNumber; entity.Update(message.Source); if (sortNumber != entity.SortNumber) { SysDicViewModel sysDicVm; if (AppContext.Instance.SysDicVms.TryGetSysDicVm(entity.DicId, out sysDicVm)) { sysDicVm.OnPropertyChanged(nameof(sysDicVm.SysDicItems)); sysDicVm.OnPropertyChanged(nameof(sysDicVm.SysDicItemsSelect)); } } } }); On <SysDicItemRemovedEvent>("删除了系统字典项后调整VM内存", LogEnum.DevConsole, action: (message) => { _dicById.Remove(message.Source.GetId()); OnPropertyChangeds(); SysDicViewModel sysDicVm; if (AppContext.Instance.SysDicVms.TryGetSysDicVm(message.Source.DicId, out sysDicVm)) { sysDicVm.OnPropertyChanged(nameof(sysDicVm.SysDicItems)); sysDicVm.OnPropertyChanged(nameof(sysDicVm.SysDicItemsSelect)); } }); Init(); #if DEBUG Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {this.GetType().Name}.ctor"); #endif }
private GpuProfileViewModels() { if (WpfUtil.IsInDesignMode) { return; } #if DEBUG NTStopwatch.Start(); #endif VirtualRoot.AddEventPath <GpuProfileSetRefreshedEvent>("Gpu超频集合刷新后刷新附着在当前币种上的超频数据", LogEnum.DevConsole, action: 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()); AddEventPath <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 (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()); #if DEBUG var elapsedMilliseconds = NTStopwatch.Stop(); if (elapsedMilliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { Write.DevTimeSpan($"耗时{elapsedMilliseconds} {this.GetType().Name}.ctor"); } #endif }
/// <summary> /// 命令窗口。使用该方法的代码行应将前两个参数放在第一行以方便vs查找引用时展示出参数信息 /// </summary> private static DelegateHandler <TCmd> Window <TCmd>(string description, LogEnum logType, Action <TCmd> action) where TCmd : ICmd { return(VirtualRoot.Path(description, logType, action).AddToCollection(_contextHandlers)); }
public void RefreshAutoBootStart() { VirtualRoot.Execute(new RefreshAutoBootStartCommand()); }
public void RefreshIsRemoteDesktopEnabled() { VirtualRoot.Execute(new RefreshIsRemoteDesktopEnabledCommand()); }
private void Link() { VirtualRoot.BuildCmdPath <CloseNTMinerCommand>(action: message => { UIThread.Execute(() => { try { Shutdown(); } catch (Exception e) { Logger.ErrorDebugLine(e); Environment.Exit(0); } }); }); #region 周期确保守护进程在运行 VirtualRoot.BuildEventPath <Per1MinuteEvent>("周期确保守护进程在运行", LogEnum.DevConsole, action: message => { Daemon.DaemonUtil.RunNTMinerDaemon(); }); #endregion #region 开始和停止挖矿后 VirtualRoot.BuildEventPath <MineStartedEvent>("启动1080ti小药丸、启动DevConsole? 更新挖矿按钮状态", LogEnum.DevConsole, action: message => { AppContext.Instance.MinerProfileVm.IsMining = true; StartStopMineButtonViewModel.Instance.BtnStopText = "正在挖矿"; // 启动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.BuildEventPath <MineStopedEvent>("停止挖矿后停止1080ti小药丸 挖矿停止后更新界面挖矿状态", LogEnum.DevConsole, action: message => { AppContext.Instance.MinerProfileVm.IsMining = false; StartStopMineButtonViewModel.Instance.BtnStopText = "尚未开始"; OhGodAnETHlargementPill.OhGodAnETHlargementPillUtil.Stop(); }); #endregion #region 处理禁用win10系统更新 VirtualRoot.BuildCmdPath <BlockWAUCommand>(action: message => { NTMiner.Windows.WindowsUtil.BlockWAU(); }); #endregion #region 优化windows VirtualRoot.BuildCmdPath <Win10OptimizeCommand>(action: message => { NTMiner.Windows.WindowsUtil.Win10Optimize(); }); #endregion #region 处理开启A卡计算模式 VirtualRoot.BuildCmdPath <SwitchRadeonGpuCommand>(action: message => { if (NTMinerRoot.Instance.GpuSet.GpuType == GpuType.AMD) { SwitchRadeonGpuMode(message.On); } }); #endregion #region 处理A卡驱动签名 VirtualRoot.BuildCmdPath <AtikmdagPatcherCommand>(action: message => { if (NTMinerRoot.Instance.GpuSet.GpuType == GpuType.AMD) { AtikmdagPatcher.AtikmdagPatcherUtil.Run(); } }); #endregion #region 启用或禁用windows远程桌面 VirtualRoot.BuildCmdPath <EnableWindowsRemoteDesktopCommand>(action: message => { if (NTMinerRegistry.GetIsRemoteDesktopEnabled()) { return; } string msg = "确定启用Windows远程桌面吗?"; DialogWindow.ShowDialog(new DialogWindowViewModel( message: msg, title: "确认", onYes: () => { Rdp.SetRdpEnabled(true, true); Firewall.AddRemoteDesktopRule(); })); }); #endregion #region 启用或禁用windows开机自动登录 VirtualRoot.BuildCmdPath <EnableOrDisableWindowsAutoLoginCommand>(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); 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); if (IsMinerClient) { NTMinerRegistry.SetIsLastIsWork(true); } return; } else { if (IsMinerClient) { NTMinerRegistry.SetIsLastIsWork(false); } } // 如果是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); AppVersionChangedEvent.PublishIfNewVersion(minerClientVersion); }); } else { Logger.InfoDebugLine("GetAliyunServerJson下载失败"); } DoInit(isWork, callback); }); #region 发生了用户活动时检查serverJson是否有新版本 VirtualRoot.On <UserActionEvent>("发生了用户活动时检查serverJson是否有新版本", LogEnum.DevConsole, action: message => { OfficialServer.GetJsonFileVersionAsync(AssemblyInfo.ServerJsonFileName, (serverJsonFileVersion, minerClientVersion) => { AppVersionChangedEvent.PublishIfNewVersion(minerClientVersion); 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(); }); }
private void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e) { VirtualRoot.ThisLocalInfo(nameof(NTMinerContext), $"Windows 会话切换, 因为{((WindowsSessionSwitchReason)e.Reason).GetDescription()}"); }
public void Init(Action callback) { Task.Factory.StartNew(() => { bool isSelfWork = Environment.GetCommandLineArgs().Contains("--selfWork", StringComparer.OrdinalIgnoreCase); bool isWork = isSelfWork || Environment.GetCommandLineArgs().Contains("--work", StringComparer.OrdinalIgnoreCase); _workType = isSelfWork ? WorkType.SelfWork : (isWork ? WorkType.MineWork : WorkType.None); if (ClientAppType.IsMinerClient) { NTMinerRegistry.SetWorkType(_workType); } if (isWork) { DoInit(callback); } else { // 如果是Debug模式且不是群控客户端则使用本地数据库初始化 bool useLocalDb = DevMode.IsDevMode && !ClientAppType.IsMinerStudio; if (useLocalDb) { DoInit(callback); } else { Logger.InfoDebugLine(nameof(GetAliyunServerJson)); GetAliyunServerJson((data) => { // 如果server.json未下载成功则不覆写本地server.json if (data != null && data.Length != 0) { Logger.InfoDebugLine($"{nameof(GetAliyunServerJson)}成功"); var serverJson = Encoding.UTF8.GetString(data); if (!string.IsNullOrEmpty(serverJson)) { HomePath.WriteServerJsonFile(serverJson); } RpcRoot.OfficialServer.AppSettingService.GetJsonFileVersionAsync(HomePath.ExportServerJsonFileName, serverState => { SetServerJsonVersion(serverState.JsonFileVersion); AppVersionChangedEvent.PublishIfNewVersion(serverState.MinerClientVersion); if (Math.Abs((long)Timestamp.GetTimestamp() - (long)serverState.Time) >= Timestamp.DesyncSeconds) { NTMinerConsole.UserWarn($"本机和服务器时间不同步,请调整,本地:{DateTime.Now.ToString()},服务器:{Timestamp.FromTimestamp(serverState.Time).ToString()}。此问题不影响挖矿。"); } }); } else { if (!File.Exists(HomePath.ServerJsonFileFullName)) { VirtualRoot.ThisLocalError(nameof(NTMinerContext), "配置文件下载失败,这是第一次运行开源矿工,配置文件至少需要成功下载一次,请检查网络是否可用", OutEnum.Warn); } else { VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), "配置文件下载失败,使用最近一次成功下载的配置文件"); } } DoInit(callback); }); #region 发生了用户活动时检查serverJson是否有新版本 VirtualRoot.AddEventPath <UserActionEvent>("发生了用户活动时检查serverJson是否有新版本", LogEnum.DevConsole, action: message => { RefreshServerJsonFile(); }, location: this.GetType()); #endregion } } VirtualRoot.ThisLocalInfo(nameof(NTMinerContext), $"启动{VirtualRoot.AppName}"); }); }
private void Link() { VirtualRoot.AddCmdPath <RegCmdHereCommand>(action: message => { try { Windows.Cmd.RegCmdHere(); VirtualRoot.ThisLocalInfo(nameof(NTMinerContext), "添加windows右键命令行成功"); } catch (Exception e) { Logger.ErrorDebugLine(e); VirtualRoot.ThisLocalError(nameof(NTMinerContext), "添加windows右键命令行失败", OutEnum.Warn); } }, location: this.GetType()); VirtualRoot.AddCmdPath <UnRegCmdHereCommand>(action: message => { try { Windows.Cmd.UnRegCmdHere(); VirtualRoot.ThisLocalInfo(nameof(NTMinerContext), "移除windows右键命令行成功"); } catch (Exception e) { Logger.ErrorDebugLine(e); VirtualRoot.ThisLocalError(nameof(NTMinerContext), "移除windows右键命令行失败", OutEnum.Warn); } }, location: this.GetType()); VirtualRoot.AddEventPath <Per1MinuteEvent>("每1分钟阻止系统休眠", LogEnum.None, action: message => { Power.PreventSleep(); }, location: this.GetType()); #region 挖矿开始时将无份额内核重启份额计数置0 int shareCount = 0; DateTime shareOn = DateTime.Now; DateTime hightSpeedOn = DateTime.Now; VirtualRoot.AddEventPath <MineStartedEvent>("挖矿开始后将无份额内核重启份额计数置0", LogEnum.DevConsole, action: message => { // 将无份额内核重启份额计数置0 shareCount = 0; hightSpeedOn = DateTime.Now; if (!message.MineContext.IsRestart) { // 当不是内核重启时更新shareOn,如果是内核重启不用更新shareOn从而给不干扰无内核矿机重启的逻辑 shareOn = DateTime.Now; } }, location: this.GetType()); #endregion #region 每20秒钟检查是否需要重启 VirtualRoot.AddEventPath <Per20SecondEvent>("每20秒钟检查是否需要重启", LogEnum.None, action: 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) { hightSpeedOn = message.BornOn; } } if (hightSpeedOn.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 { hightSpeedOn = 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) { if ((DateTime.Now - LockedMineContext.MineStartedOn).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) { if (restartComputer) { 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; // 退出 } // 产生过份额或者已经两倍重启内核时间了 if (restartKernel && (totalShare > 0 || (DateTime.Now - shareOn).TotalMinutes > 2 * MinerProfile.NoShareRestartKernelMinutes)) { VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), $"{MinerProfile.NoShareRestartKernelMinutes.ToString()}分钟无份额重启内核", toConsole: true); RestartMine(); return; // 退出 } } if (totalShare > shareCount) { shareCount = totalShare; shareOn = DateTime.Now; } }
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); }); try { appMutex = new Mutex(true, s_appPipName, out createdNew); } catch (Exception) { createdNew = false; } if (createdNew) { this.ShutdownMode = ShutdownMode.OnExplicitShutdown; NotiCenterWindow.Instance.Show(); LoginWindow loginWindow = new LoginWindow(); var result = loginWindow.ShowDialog(); if (result.HasValue && result.Value) { bool isInnerIp = Ip.Util.IsInnerIp(NTMinerRegistry.GetControlCenterHost()); if (isInnerIp) { NTMinerServices.NTMinerServicesUtil.RunNTMinerServices(() => { Init(); }); } else { Init(); } } VirtualRoot.Window <CloseNTMinerCommand>("处理关闭群控客户端命令", LogEnum.UserConsole, action: message => { UIThread.Execute(() => { try { Shutdown(); } catch (Exception ex) { Logger.ErrorDebugLine(ex); Environment.Exit(0); } }); }); } else { try { _appViewFactory.ShowMainWindow(this, MinerServer.NTMinerAppType.MinerStudio); } catch (Exception) { DialogWindow.ShowDialog(message: "另一个NTMiner正在运行,请手动结束正在运行的NTMiner进程后再次尝试。", title: "alert", 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); #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).TotalHours > MinerProfile.PeriodicRestartComputerHours) { Logger.WarnWriteLine($"每运行{MinerProfile.PeriodicRestartKernelHours}小时重启电脑"); Windows.Power.Restart(); return; // 退出 } } } catch (Exception e) { Logger.ErrorDebugLine(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); } #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; } }
private KernelOutputTranslaterViewModels() { if (WpfUtil.IsInDesignMode) { return; } VirtualRoot.AddEventPath <ServerContextReInitedEvent>("ServerContext刷新后刷新VM内存", LogEnum.DevConsole, action: message => { _dicById.Clear(); _dicByKernelOutputId.Clear(); Init(); }, location: this.GetType()); VirtualRoot.AddEventPath <ServerContextReInitedEventHandledEvent>("ServerContext的VM集刷新后刷新视图界面", LogEnum.DevConsole, action: message => { OnPropertyChanged(nameof(AllKernelOutputTranslaterVms)); }, location: this.GetType()); AddEventPath <KernelOutputTranslaterAddedEvent>("添加了内核输出翻译器后刷新VM内存", LogEnum.DevConsole, action: message => { if (KernelOutputVms.TryGetKernelOutputVm(message.Source.KernelOutputId, out KernelOutputViewModel kernelOutputVm)) { if (!_dicByKernelOutputId.ContainsKey(message.Source.KernelOutputId)) { _dicByKernelOutputId.Add(message.Source.KernelOutputId, new List <KernelOutputTranslaterViewModel>()); } var vm = new KernelOutputTranslaterViewModel(message.Source); _dicByKernelOutputId[message.Source.KernelOutputId].Add(vm); _dicById.Add(message.Source.GetId(), vm); kernelOutputVm.OnPropertyChanged(nameof(kernelOutputVm.KernelOutputTranslaters)); } }, location: this.GetType()); AddEventPath <KernelOutputTranslaterUpdatedEvent>("更新了内核输出翻译器后刷新VM内存", LogEnum.DevConsole, action: message => { if (_dicByKernelOutputId.TryGetValue(message.Source.KernelOutputId, out List <KernelOutputTranslaterViewModel> vms)) { var vm = vms.FirstOrDefault(a => a.Id == message.Source.GetId()); if (vm != null) { vm.Update(message.Source); } } }, location: this.GetType()); AddEventPath <KernelOutputTranslaterRemovedEvent>("移除了内核输出翻译器后刷新VM内存", LogEnum.DevConsole, action: message => { if (_dicByKernelOutputId.ContainsKey(message.Source.KernelOutputId)) { var item = _dicByKernelOutputId[message.Source.KernelOutputId].FirstOrDefault(a => a.Id == message.Source.GetId()); if (item != null) { _dicByKernelOutputId[message.Source.KernelOutputId].Remove(item); } } if (_dicById.ContainsKey(message.Source.GetId())) { _dicById.Remove(message.Source.GetId()); } if (KernelOutputVms.TryGetKernelOutputVm(message.Source.KernelOutputId, out KernelOutputViewModel kernelOutputVm)) { kernelOutputVm.OnPropertyChanged(nameof(kernelOutputVm.KernelOutputTranslaters)); } }, location: this.GetType()); Init(); }
private CoinViewModels() { if (WpfUtil.IsInDesignMode) { return; } VirtualRoot.BuildEventPath <ServerContextReInitedEvent>("ServerContext刷新后刷新VM内存", LogEnum.DevConsole, path: message => { _dicById.Clear(); Init(); }, location: this.GetType()); VirtualRoot.BuildEventPath <ServerContextReInitedEventHandledEvent>("ServerContext的VM集刷新后刷新视图界面", LogEnum.DevConsole, path: message => { AllPropertyChanged(); }, location: this.GetType()); BuildEventPath <CoinAddedEvent>("添加了币种后刷新VM内存", LogEnum.DevConsole, path: (message) => { _dicById.Add(message.Source.GetId(), new CoinViewModel(message.Source)); AllPropertyChanged(); VirtualRoot.RaiseEvent(new CoinVmAddedEvent(message)); }, location: this.GetType()); BuildEventPath <CoinRemovedEvent>("移除了币种后刷新VM内存", LogEnum.DevConsole, path: message => { _dicById.Remove(message.Source.GetId()); AllPropertyChanged(); VirtualRoot.RaiseEvent(new CoinVmRemovedEvent(message)); }, location: this.GetType()); BuildEventPath <CoinKernelVmAddedEvent>("币种内核Vm集添加了新Vm后刷新币种Vm集的关联内存", LogEnum.DevConsole, path: message => { if (_dicById.TryGetValue(message.Event.Source.CoinId, out CoinViewModel coinVm)) { coinVm.OnPropertyChanged(nameof(CoinViewModel.CoinKernel)); coinVm.OnPropertyChanged(nameof(CoinViewModel.CoinKernels)); coinVm.OnPropertyChanged(nameof(CoinViewModel.IsSupported)); } }, this.GetType()); BuildEventPath <CoinKernelVmRemovedEvent>("币种内核Vm集删除了新Vm后刷新币种Vm集的关联内存", LogEnum.DevConsole, path: message => { if (_dicById.TryGetValue(message.Event.Source.CoinId, out CoinViewModel coinVm)) { coinVm.OnPropertyChanged(nameof(CoinViewModel.CoinKernel)); coinVm.OnPropertyChanged(nameof(CoinViewModel.CoinKernels)); coinVm.OnPropertyChanged(nameof(CoinViewModel.IsSupported)); } }, this.GetType()); BuildEventPath <CoinUpdatedEvent>("更新了币种后刷新VM内存", LogEnum.DevConsole, path: message => { if (_dicById.TryGetValue(message.Source.GetId(), out CoinViewModel vm)) { bool justAsDualCoin = vm.JustAsDualCoin; vm.Update(message.Source); vm.TestWalletVm.Address = message.Source.TestWallet; vm.OnPropertyChanged(nameof(vm.Wallets)); vm.OnPropertyChanged(nameof(vm.WalletItems)); if (MinerProfileVm.CoinId == message.Source.GetId()) { MinerProfileVm.OnPropertyChanged(nameof(MinerProfileVm.CoinVm)); } CoinKernelViewModel coinKernelVm = MinerProfileVm.CoinVm.CoinKernel; if (coinKernelVm != null && coinKernelVm.CoinKernelProfile.SelectedDualCoin != null && coinKernelVm.CoinKernelProfile.SelectedDualCoin.GetId() == message.Source.GetId()) { coinKernelVm.CoinKernelProfile.OnPropertyChanged(nameof(coinKernelVm.CoinKernelProfile.SelectedDualCoin)); } if (justAsDualCoin != vm.JustAsDualCoin) { OnPropertyChanged(nameof(MainCoins)); } } }, location: this.GetType()); BuildEventPath <CoinIconDownloadedEvent>("下载了币种图标后", LogEnum.DevConsole, path: message => { try { if (string.IsNullOrEmpty(message.Source.Icon)) { return; } string iconFileFullName = MinerClientTempPath.GetIconFileFullName(message.Source.Icon); if (string.IsNullOrEmpty(iconFileFullName) || !File.Exists(iconFileFullName)) { return; } if (_dicById.TryGetValue(message.Source.GetId(), out CoinViewModel coinVm)) { try { coinVm.IconImageSource = new Uri(iconFileFullName, UriKind.Absolute).ToString(); } catch (Exception e) { File.Delete(iconFileFullName); Logger.ErrorDebugLine(e); } } } catch (Exception e) { Logger.ErrorDebugLine(e); } }, location: this.GetType()); Init(); }
private static List <IncomeItem> PickIncomeItems(string html) { try { List <IncomeItem> results = new List <IncomeItem>(); if (string.IsNullOrEmpty(html)) { return(results); } string patternFileFullName = Path.Combine(HomePath.AppDomainBaseDirectory, "pattern.txt"); if (!File.Exists(patternFileFullName)) { return(results); } string pattern = File.ReadAllText(patternFileFullName); if (string.IsNullOrEmpty(pattern)) { return(results); } List <int> indexList = new List <int>(); const string splitText = "<tr class=\"row-common"; int index = html.IndexOf(splitText); while (index != -1) { indexList.Add(index); index = html.IndexOf(splitText, index + splitText.Length); } Regex regex = VirtualRoot.GetRegex(pattern); int maxLen = 0; for (int i = 0; i < indexList.Count; i++) { IncomeItem incomeItem; if (i + 1 < indexList.Count) { int len = indexList[i + 1] - indexList[i]; if (len > maxLen) { maxLen = len; } incomeItem = PickIncomeItem(regex, html.Substring(indexList[i], len)); } else { string content = html.Substring(indexList[i]); if (content.Length > maxLen) { content = content.Substring(0, maxLen); } incomeItem = PickIncomeItem(regex, content); } if (incomeItem != null) { results.Add(incomeItem); } } return(results); } catch (Exception e) { Logger.ErrorDebugLine(e); return(new List <IncomeItem>()); } }
public static void Upgrade(NTMinerAppType appType, string fileName, Action callback) { RpcRoot.OfficialServer.FileUrlService.GetNTMinerUpdaterUrlAsync((downloadFileUrl, e) => { try { string argument = string.Empty; if (!string.IsNullOrEmpty(fileName)) { argument = "ntminerFileName=" + fileName; } if (appType == NTMinerAppType.MinerStudio) { 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(); } }); }
public void ReportWsDaemonState([FromBody] WsClientState state) { VirtualRoot.Execute(new RefreshWsStateCommand(state)); }
private CoinViewModels() { #if DEBUG Write.Stopwatch.Start(); #endif if (WpfUtil.IsInDesignMode) { return; } VirtualRoot.BuildEventPath <ServerContextReInitedEvent>("ServerContext刷新后刷新VM内存", LogEnum.DevConsole, action: message => { _dicById.Clear(); Init(); }); VirtualRoot.BuildEventPath <ServerContextVmsReInitedEvent>("ServerContext的VM集刷新后刷新视图界面", LogEnum.DevConsole, action: message => { AllPropertyChanged(); }); BuildEventPath <CoinAddedEvent>("添加了币种后刷新VM内存", LogEnum.DevConsole, action: (message) => { _dicById.Add(message.Source.GetId(), new CoinViewModel(message.Source)); AppContext.Instance.MinerProfileVm.OnPropertyChanged(nameof(NTMiner.AppContext.Instance.MinerProfileVm.CoinVm)); AllPropertyChanged(); }); BuildEventPath <CoinRemovedEvent>("移除了币种后刷新VM内存", LogEnum.DevConsole, action: message => { _dicById.Remove(message.Source.GetId()); AppContext.Instance.MinerProfileVm.OnPropertyChanged(nameof(NTMiner.AppContext.Instance.MinerProfileVm.CoinVm)); AllPropertyChanged(); }); BuildEventPath <CoinUpdatedEvent>("更新了币种后刷新VM内存", LogEnum.DevConsole, action: message => { CoinViewModel coinVm = _dicById[message.Source.GetId()]; bool justAsDualCoin = coinVm.JustAsDualCoin; coinVm.Update(message.Source); coinVm.TestWalletVm.Address = message.Source.TestWallet; coinVm.OnPropertyChanged(nameof(coinVm.Wallets)); coinVm.OnPropertyChanged(nameof(coinVm.WalletItems)); if (AppContext.Instance.MinerProfileVm.CoinId == message.Source.GetId()) { AppContext.Instance.MinerProfileVm.OnPropertyChanged(nameof(NTMiner.AppContext.Instance.MinerProfileVm.CoinVm)); } CoinKernelViewModel coinKernelVm = AppContext.Instance.MinerProfileVm.CoinVm.CoinKernel; if (coinKernelVm != null && coinKernelVm.CoinKernelProfile.SelectedDualCoin != null && coinKernelVm.CoinKernelProfile.SelectedDualCoin.GetId() == message.Source.GetId()) { coinKernelVm.CoinKernelProfile.OnPropertyChanged(nameof(coinKernelVm.CoinKernelProfile.SelectedDualCoin)); } if (justAsDualCoin != coinVm.JustAsDualCoin) { OnPropertyChanged(nameof(MainCoins)); } }); BuildEventPath <CoinIconDownloadedEvent>("下载了币种图标后", LogEnum.DevConsole, action: message => { try { if (string.IsNullOrEmpty(message.Source.Icon)) { return; } string iconFileFullName = SpecialPath.GetIconFileFullName(message.Source); if (string.IsNullOrEmpty(iconFileFullName) || !File.Exists(iconFileFullName)) { return; } if (_dicById.TryGetValue(message.Source.GetId(), out CoinViewModel coinVm)) { try { coinVm.IconImageSource = new Uri(iconFileFullName, UriKind.Absolute).ToString(); } catch (Exception e) { File.Delete(iconFileFullName); Logger.ErrorDebugLine(e); } } } catch (Exception e) { Logger.ErrorDebugLine(e); } }); Init(); #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.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()}=================="); if (!NTMiner.Windows.WMI.IsWmiEnabled) { DialogWindow.ShowDialog(new DialogWindowViewModel( message: "开源矿工无法运行所需的组件,因为本机未开启WMI服务,开源矿工需要使用WMI服务检测windows的内存、显卡等信息,请先手动开启WMI。", title: "提醒", icon: "Icon_Error")); Shutdown(); Environment.Exit(0); } NotiCenterWindowViewModel.IsHotKeyEnabled = true; ConsoleWindow.Instance.Show(); NotiCenterWindow.Instance.Show(); if (!NTMiner.Windows.Role.IsAdministrator) { NotiCenterWindowViewModel.Instance.Manager .CreateMessage() .Warning("请以管理员身份运行。") .WithButton("点击以管理员身份运行", button => { WpfUtil.RunAsAdministrator(); }) .Dismiss().WithButton("忽略", button => { }).Queue(); } VirtualRoot.BuildEventPath <StartingMineFailedEvent>("开始挖矿失败", LogEnum.DevConsole, action: message => { AppContext.Instance.MinerProfileVm.IsMining = false; VirtualRoot.Out.ShowError(message.Message); }); NTMinerRoot.Instance.Init(() => { _appViewFactory.Link(); if (VirtualRoot.IsLTWin10) { VirtualRoot.ThisWorkerWarn(nameof(App), AppStatic.LowWinMessage, toConsole: true); } if (NTMinerRoot.Instance.GpuSet.Count == 0) { VirtualRoot.ThisWorkerError(nameof(App), "没有矿卡或矿卡未驱动。", toConsole: true); } if (NTMinerRoot.Instance.CoinSet.Count == 0) { VirtualRoot.ThisWorkerError(nameof(App), "访问阿里云失败,请尝试更换本机dns解决此问题。", toConsole: true); } UIThread.Execute(() => { if (NTMinerRoot.Instance.MinerProfile.IsNoUi && NTMinerRoot.Instance.MinerProfile.IsAutoStart) { ConsoleWindow.Instance.Hide(); VirtualRoot.Out.ShowSuccess("已切换为无界面模式运行,可在选项页调整设置", "开源矿工"); } else { _appViewFactory.ShowMainWindow(isToggle: false); } StartStopMineButtonViewModel.Instance.AutoStart(); AppContext.NotifyIcon = ExtendedNotifyIcon.Create("开源矿工", isMinerStudio: false); ConsoleWindow.Instance.HideSplash(); }); #region 处理显示主界面命令 VirtualRoot.BuildCmdPath <ShowMainWindowCommand>(action: message => { ShowMainWindow(message.IsToggle); }); #endregion Task.Factory.StartNew(() => { try { HttpServer.Start($"http://localhost:{VirtualRoot.MinerClientPort}"); Daemon.DaemonUtil.RunNTMinerDaemon(); } catch (Exception ex) { Logger.ErrorDebugLine(ex); } }); }); Link(); } else { try { _appViewFactory.ShowMainWindow(this, MinerServer.NTMinerAppType.MinerClient); } catch (Exception) { DialogWindow.ShowDialog(new DialogWindowViewModel( message: "另一个NTMiner正在运行,请手动结束正在运行的NTMiner进程后再次尝试。", title: "提醒", icon: "Icon_Error")); Process currentProcess = Process.GetCurrentProcess(); NTMiner.Windows.TaskKill.KillOtherProcess(currentProcess); } } } base.OnStartup(e); }
protected override void OnStartup(StartupEventArgs e) { // 之所以提前到这里是因为升级之前可能需要下载升级器,下载升级器时需要下载器 VirtualRoot.AddCmdPath <ShowFileDownloaderCommand>(action: message => { FileDownloader.ShowWindow(message.DownloadFileUrl, message.FileTitle, message.DownloadComplete); }, location: this.GetType()); VirtualRoot.AddCmdPath <UpgradeCommand>(action: 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.AddOnecePath <ClientSetInitedEvent>("矿工集合初始化完成后刷新矿机列表界面", LogEnum.DevConsole, action: 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.AddCmdPath <ShowMainWindowCommand>(action: 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); }
/// <summary> /// 事件响应 /// </summary> private static DelegateHandler <TEvent> On <TEvent>(string description, LogEnum logType, Action <TEvent> action) where TEvent : IEvent { return(VirtualRoot.Path(description, logType, action).AddToCollection(_contextHandlers)); }
static void Main(string[] args) { if (args.Length != 0) { if (args.Contains("--sha1")) { File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sha1"), Sha1); return; } } try { VirtualRoot.StartTimer(); if (!Debugger.IsAttached && DevMode.IsDevMode) { Write.Init(); } _waitHandle = new AutoResetEvent(false); bool mutexCreated; try { _sMutexApp = new Mutex(true, "NTMinerDaemonAppMutex", out mutexCreated); } catch { mutexCreated = false; } if (mutexCreated) { NTMinerRegistry.SetDaemonVersion(Sha1); NTMinerRegistry.SetAutoBoot("NTMinerDaemon", true); bool isAutoBoot = NTMinerRegistry.GetIsAutoBoot(); if (isAutoBoot) { string location = NTMinerRegistry.GetLocation(); if (!string.IsNullOrEmpty(location) && File.Exists(location)) { string processName = Path.GetFileName(location); Process[] processes = Process.GetProcessesByName(processName); if (processes.Length == 0) { string arguments = NTMinerRegistry.GetArguments(); if (NTMinerRegistry.GetIsLastIsWork()) { arguments = "--work " + arguments; } try { Process.Start(location, arguments); Write.DevOk($"启动挖矿端 {location} {arguments}"); } catch (Exception e) { Logger.ErrorDebugLine($"启动挖矿端失败因为异常 {location} {arguments}", e); } } else { Write.DevDebug($"挖矿端已经在运行中无需启动"); } } } else { Write.DevDebug($"挖矿端未设置为自动启动"); } Run(); } } catch (Exception e) { Logger.ErrorDebugLine(e); } }
public void OverClock() { VirtualRoot.ThisWorkerInfo(nameof(MinerClientController), $"刷新超频", toConsole: true); NTMinerRoot.Instance.GpuProfileSet.Refresh(); }
// 创建管道,将输出通过管道转送到日志文件,然后读取日志文件内容打印到控制台 private static void CreatePipProcess(IMineContext mineContext, string cmdLine) { 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 }; if (CreateProcess( lpApplicationName: null, lpCommandLine: new StringBuilder(cmdLine), lpProcessAttributes: IntPtr.Zero, lpThreadAttributes: IntPtr.Zero, bInheritHandles: true, dwCreationFlags: NORMAL_PRIORITY_CLASS, lpEnvironment: IntPtr.Zero, lpCurrentDirectory: SpecialPath.KernelsDirFullName, lpStartupInfo: ref lpStartupInfo, lpProcessInformation: out _)) { if (bret == false) { int lasterr = Marshal.GetLastWin32Error(); Write.UserLine($"管道型进程创建失败 lasterr:{lasterr}", ConsoleColor.Red); } 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); }); ReadPrintLoopLogFileAsync(mineContext, pipLogFileFullName); } } else { Logger.ErrorWriteLine("内核启动失败,请重试"); } }
static void Main() { VirtualRoot.SetOut(new ConsoleOut()); NTMinerConsole.MainUiOk(); NTMinerConsole.DisbleQuickEditMode(); DevMode.SetDevMode(); Windows.ConsoleHandler.Register(Exit); try { bool mutexCreated; try { // 锁名称上带上本节点的端口号,从而允许一个服务器上运行多个WebApiServer节点,这在软升级服务端程序时有用。 // 升级WebApiServer程序的时候步骤是: // 1,在另一个端口启动新版本的程序; // 2,让Widnows将来自旧端口的所有tcp请求转发到新端口; // 3,退出旧版本的程序并更新到新版本; // 4,删除第2步添加的Windows的端口转发; // 5,退出第1步运行的节点; // TODO:实现软升级策略 _sMutexApp = new Mutex(true, $"NTMinerServicesMutex{ServerRoot.HostConfig.GetServerPort().ToString()}", out mutexCreated); } catch { mutexCreated = false; } if (mutexCreated) { try { // 用本节点的地址作为队列名,消费消息时根据路由键区分消息类型 string queue = $"{nameof(ServerAppType.WebApiServer)}.{ServerRoot.HostConfig.ThisServerAddress}"; string durableQueue = queue + MqKeyword.DurableQueueEndsWith; string wsBreathQueue = queue + MqKeyword.WsBreathQueueEndsWith; AbstractMqMessagePath[] mqMessagePaths = new AbstractMqMessagePath[] { new UserMqMessagePath(durableQueue), new MinerClientMqMessagePath(queue), new WsBreathMqMessagePath(wsBreathQueue), new OperationMqMessagePath(queue), new MqCountMqMessagePath(queue), new ClientTestIdMqMessagePath(queue) }; if (!MqRedis.Create(ServerAppType.WebApiServer, mqMessagePaths, out IMqRedis mqRedis)) { NTMinerConsole.UserError("启动失败,无法继续,因为服务器上下文创建失败"); return; } Console.Title = $"{nameof(ServerAppType.WebApiServer)}_{ServerRoot.HostConfig.ThisServerAddress}"; // 阿里云OSS坑爹比七牛Kodo贵一半 CloudFileUrlGenerater = new AliCloudOSSFileUrlGenerater(); IRedis redis = mqRedis; IMq mq = mqRedis; AdminMqSender = new AdminMqSender(mq); ClientTestIdDataRedis = new ClientTestIdDataRedis(redis); var minerClientMqSender = new MinerClientMqSender(mq); var userMqSender = new UserMqSender(mq); var minerRedis = new MinerDataRedis(redis); var clientActiveOnRedis = new ClientActiveOnRedis(redis); var speedDataRedis = new SpeedDataRedis(redis); var userRedis = new UserDataRedis(redis); var captchaRedis = new CaptchaDataRedis(redis); MqCountSet = new MqCountSet(); WsServerNodeRedis = new WsServerNodeRedis(redis); WsServerNodeAddressSet = new WsServerNodeAddressSet(WsServerNodeRedis); UserSet = new UserSet(userRedis, userMqSender); UserAppSettingSet = new UserAppSettingSet(); CaptchaSet = new CaptchaSet(captchaRedis); CalcConfigSet = new CalcConfigSet(); NTMinerWalletSet = new NTMinerWalletSet(); GpuNameSet = new GpuNameSet(); ClientDataSet clientDataSet = new ClientDataSet(minerRedis, clientActiveOnRedis, speedDataRedis, minerClientMqSender); ClientDataSet = clientDataSet; var operationMqSender = new OperationMqSender(mqRedis); MineWorkSet = new UserMineWorkSet(operationMqSender); MinerGroupSet = new UserMinerGroupSet(); NTMinerFileSet = new NTMinerFileSet(); OverClockDataSet = new OverClockDataSet(); KernelOutputKeywordSet = new KernelOutputKeywordSet(SpecialPath.LocalDbFileFullName); ServerMessageSet = new ServerMessageSet(SpecialPath.LocalDbFileFullName); if (VirtualRoot.LocalAppSettingSet.TryGetAppSetting(nameof(KernelOutputKeywordTimestamp), out IAppSetting appSetting) && appSetting.Value is DateTime value) { KernelOutputKeywordTimestamp = value; } else { KernelOutputKeywordTimestamp = Timestamp.UnixBaseTime; } } catch (Exception e) { NTMinerConsole.UserError(e.Message); NTMinerConsole.UserError(e.StackTrace); NTMinerConsole.UserInfo("按任意键退出"); Console.ReadKey(); return; } VirtualRoot.StartTimer(); NTMinerRegistry.SetAutoBoot("NTMinerServices", true); Type thisType = typeof(AppRoot); Run(); } } catch (Exception e) { Logger.ErrorDebugLine(e); } }
protected override void OnExit(ExitEventArgs e) { VirtualRoot.RaiseEvent(new AppExitEvent()); base.OnExit(e); NTMinerConsole.Free(); }
public static void Upgrade(string fileName, Action callback) { try { string updaterDirFullName = Path.Combine(VirtualRoot.GlobalDirFullName, "Updater"); if (!Directory.Exists(updaterDirFullName)) { Directory.CreateDirectory(updaterDirFullName); } OfficialServer.FileUrlService.GetNTMinerUpdaterUrlAsync((downloadFileUrl, e) => { try { string ntMinerUpdaterFileFullName = Path.Combine(updaterDirFullName, "NTMinerUpdater.exe"); string argument = string.Empty; if (!string.IsNullOrEmpty(fileName)) { argument = "ntminerFileName=" + fileName; } if (VirtualRoot.IsMinerStudio) { argument += " --minerstudio"; } if (string.IsNullOrEmpty(downloadFileUrl)) { if (File.Exists(ntMinerUpdaterFileFullName)) { NTMiner.Windows.Cmd.RunClose(ntMinerUpdaterFileFullName, 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(ntMinerUpdaterFileFullName) || uri.AbsolutePath != updaterVersion) { VirtualRoot.Execute(new ShowFileDownloaderCommand(downloadFileUrl, "开源矿工更新器", (window, isSuccess, message, saveFileFullName) => { try { if (isSuccess) { File.Copy(saveFileFullName, ntMinerUpdaterFileFullName, overwrite: true); File.Delete(saveFileFullName); VirtualRoot.Execute(new ChangeLocalAppSettingCommand(new AppSettingData { Key = "UpdaterVersion", Value = uri.AbsolutePath })); window?.Close(); NTMiner.Windows.Cmd.RunClose(ntMinerUpdaterFileFullName, argument); callback?.Invoke(); } else { NotiCenterWindowViewModel.Instance.Manager.ShowErrorMessage(message); callback?.Invoke(); } } catch { callback?.Invoke(); } })); } else { NTMiner.Windows.Cmd.RunClose(ntMinerUpdaterFileFullName, argument); callback?.Invoke(); } } catch { callback?.Invoke(); } }); } catch { callback?.Invoke(); } }
private void Link() { VirtualRoot.AddCmdPath <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); } }, location: this.GetType()); VirtualRoot.AddEventPath <Per1MinuteEvent>("每1分钟阻止系统休眠", LogEnum.None, action: message => { Windows.Power.PreventSleep(); }, location: this.GetType()); #region 挖矿开始时将无份额内核重启份额计数置0 int shareCount = 0; DateTime shareOn = DateTime.Now; VirtualRoot.AddEventPath <MineStartedEvent>("挖矿开始后将无份额内核重启份额计数置0", LogEnum.DevConsole, action: message => { // 将无份额内核重启份额计数置0 shareCount = 0; if (!message.MineContext.IsRestart) { shareOn = DateTime.Now; } }, location: this.GetType()); #endregion #region 每20秒钟检查是否需要重启 VirtualRoot.AddEventPath <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; } }