public void AutoStart() { bool IsAutoStart = (MinerProfile.IsAutoStart || CommandLineArgs.IsAutoStart); if (IsAutoStart && !this.MinerProfile.IsMining) { this.MinerProfile.IsMining = true; int n = MinerProfile.AutoStartDelaySeconds; IMessagePathId handler = null; handler = VirtualRoot.BuildEventPath <Per1SecondEvent>("挖矿倒计时", LogEnum.None, action: message => { if (NTMinerRoot.IsAutoStartCanceled) { BtnStopText = $"尚未开始"; n = 0; } else { BtnStopText = $"倒计时{--n}"; } if (n <= 0) { VirtualRoot.DeletePath(handler); if (!NTMinerRoot.IsAutoStartCanceled) { BtnStopText = "正在挖矿"; MinerProfile.IsMining = true; VirtualRoot.ThisWorkerInfo(nameof(StartStopMineButtonViewModel), $"自动开始挖矿", toConsole: true); NTMinerRoot.Instance.StartMine(); } } }); } }
public void AutoStart() { bool isAutoStart = (MinerProfile.IsAutoStart || CommandLineArgs.IsAutoStart); if (isAutoStart && !this.MinerProfile.IsMining) { NTMinerConsole.UserInfo($"{MinerProfile.AutoStartDelaySeconds.ToString()}秒后开始挖矿"); this.MinerProfile.IsMining = true; IMessagePathId pathId = null; pathId = VirtualRoot.BuildViaTimesLimitPath <Per1SecondEvent>("自动开始挖矿倒计时", LogEnum.None, viaTimesLimit: MinerProfile.AutoStartDelaySeconds, location: this.GetType(), PathPriority.Normal, path: message => { if (!NTMinerContext.IsAutoStartCanceled) { MineBtnText = $"倒计时{pathId.ViaTimesLimit.ToString()}"; } if (pathId.ViaTimesLimit == 0) { if (!NTMinerContext.IsAutoStartCanceled) { VirtualRoot.ThisLocalInfo(nameof(StartStopMineButtonViewModel), $"自动开始挖矿", toConsole: true); NTMinerContext.Instance.StartMine(); } } }); } }
public void RemoveMessagePath(IMessagePathId messagePathId) { if (_dicByMessageType.TryGetValue(messagePathId.MessageType, out IMessagePathSet set)) { set.RemoveMessagePath(messagePathId); } }
public void AutoStart() { bool IsAutoStart = (MinerProfile.IsAutoStart || CommandLineArgs.IsAutoStart); if (IsAutoStart && !this.MinerProfile.IsMining) { this.MinerProfile.IsMining = true; IMessagePathId handler = null; handler = VirtualRoot.BuildViaLimitPath <Per1SecondEvent>("挖矿倒计时", LogEnum.None, action: message => { if (NTMinerRoot.IsAutoStartCanceled) { BtnStopText = $"尚未开始"; } else { BtnStopText = $"倒计时{handler.ViaLimit.ToString()}"; } if (handler.ViaLimit == 0) { if (!NTMinerRoot.IsAutoStartCanceled) { BtnStopText = "正在挖矿"; MinerProfile.IsMining = true; VirtualRoot.ThisLocalInfo(nameof(StartStopMineButtonViewModel), $"自动开始挖矿", toConsole: true); NTMinerRoot.Instance.StartMine(); } } }, viaLimit: MinerProfile.AutoStartDelaySeconds); } }
public static void DeletePath(IMessagePathId handler) { if (handler == null) { return; } MessageDispatcher.Disconnect(handler); }
public static void DeletePath(IMessagePathId handler) { if (handler == null) { return; } MessageHub.RemoveMessagePath(handler); }
public static void RemoveMessagePath(IMessagePathId pathId) { if (pathId == null) { return; } MessageHub.RemovePath(pathId); }
public void RemoveMessagePath(IMessagePathId pathId) { if (pathId == null) { return; } PathSetSet.RemoveMessagePath(pathId); MessagePathRemoved?.Invoke(pathId); }
public void RemoveMessagePath(IMessagePathId messagePathId) { lock (_locker) { var item = _messagePaths.FirstOrDefault(a => ReferenceEquals(a, messagePathId)); if (item != null) { _messagePaths.Remove(item); Write.DevDebug("拆除路径" + messagePathId.Path + messagePathId.Description); } } }
public void RemoveMessagePath(IMessagePathId messagePathId) { lock (_locker) { var item = _messagePaths.FirstOrDefault(a => ReferenceEquals(a, messagePathId)); if (item != null) { _messagePaths.Remove(item); Sort(); NTMinerConsole.DevDebug(() => "拆除路径" + messagePathId.PathName + messagePathId.Description); } } }
private static void KernelProcessDaemon(IMineContext mineContext, Action clear) { if (_kernelProcessDaemon != null) { VirtualRoot.DeletePath(_kernelProcessDaemon); _kernelProcessDaemon = null; clear?.Invoke(); } string processName = mineContext.Kernel.GetProcessName(); _kernelProcessDaemon = VirtualRoot.BuildEventPath <Per1MinuteEvent>("周期性检查挖矿内核是否消失,如果消失尝试重启", LogEnum.DevConsole, action: message => { if (mineContext == Instance.LockedMineContext) { if (!string.IsNullOrEmpty(processName)) { Process[] processes = Process.GetProcessesByName(processName); if (processes.Length == 0) { mineContext.AutoRestartKernelCount += 1; VirtualRoot.ThisLocalWarn(nameof(NTMinerRoot), processName + $"挖矿内核进程消失", toConsole: true); if (Instance.MinerProfile.IsAutoRestartKernel && mineContext.AutoRestartKernelCount <= Instance.MinerProfile.AutoRestartKernelTimes) { VirtualRoot.ThisLocalInfo(nameof(NTMinerRoot), $"尝试第{mineContext.AutoRestartKernelCount.ToString()}次重启,共{Instance.MinerProfile.AutoRestartKernelTimes.ToString()}次", toConsole: true); Instance.RestartMine(); Instance.LockedMineContext.AutoRestartKernelCount = mineContext.AutoRestartKernelCount; } else { Instance.StopMineAsync(StopMineReason.KernelProcessLost); } if (_kernelProcessDaemon != null) { VirtualRoot.DeletePath(_kernelProcessDaemon); clear?.Invoke(); } } } } else { if (_kernelProcessDaemon != null) { VirtualRoot.DeletePath(_kernelProcessDaemon); _kernelProcessDaemon = null; clear?.Invoke(); } } }); }
public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { lock (_locker) { try { #if DEBUG Write.Stopwatch.Restart(); #endif // 清理除当前外的Temp/Kernel Cleaner.Instance.Clear(); #if DEBUG Write.DevTimeSpan($"耗时{Write.Stopwatch.ElapsedMilliseconds}毫秒 {nameof(MinerProcess)}.{nameof(CreateProcessAsync)}[{nameof(Cleaner)}.{nameof(Cleaner.Clear)}]"); #endif Write.UserOk("场地打扫完毕"); // 应用超频 if (Instance.GpuProfileSet.IsOverClockEnabled(mineContext.MainCoin.GetId())) { Write.UserWarn("应用超频,如果CPU性能较差耗时可能超过1分钟,请耐心等待"); var cmd = new CoinOverClockCommand(mineContext.MainCoin.GetId()); // N卡超频当cpu性能非常差时较耗时,所以这里弄个回调 IMessagePathId callback = null; callback = VirtualRoot.BuildEventPath <CoinOverClockDoneEvent>("超频完成后继续流程", LogEnum.DevConsole, message => { if (mineContext != Instance.CurrentMineContext) { VirtualRoot.DeletePath(callback); } else if (message.CmdId == cmd.Id) { VirtualRoot.DeletePath(callback); ContinueCreateProcess(mineContext); } }); VirtualRoot.Execute(cmd); } else { ContinueCreateProcess(mineContext); } } catch (Exception e) { Logger.ErrorDebugLine(e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } } }); }
public RestartWindows(RestartWindowsViewModel vm) { this.DataContext = vm; InitializeComponent(); this.OnLoaded(window => { IMessagePathId messagePathId = null; messagePathId = window.AddViaTimesLimitPath <Per1SecondEvent>("重启倒计时", LogEnum.None, action: message => { if (_isCanceled) { return; } Vm.Seconds = Vm.Seconds - 1; if (messagePathId.ViaTimesLimit == 0) { Windows.Power.Restart(); } }, Vm.Seconds, location: this.GetType()); }); }
public void Disconnect(IMessagePathId handlerId) { if (handlerId == null) { return; } lock (_locker) { _paths.Remove(handlerId.Path); var keyType = handlerId.MessageType; if (_handlers.ContainsKey(keyType) && _handlers[keyType] != null && _handlers[keyType].Count > 0 && _handlers[keyType].Contains(handlerId)) { _handlers[keyType].Remove(handlerId); Write.DevDebug("拆除路径" + handlerId.Path); Disconnected?.Invoke(handlerId); } } }
public RestartWindows() { InitializeComponent(); this.RunOneceOnLoaded(window => { IMessagePathId messagePathId = null; messagePathId = window.AddViaLimitPath <Per1SecondEvent>("重启倒计时", LogEnum.None, action: message => { if (_isCanceled) { return; } Vm.Seconds = Vm.Seconds - 1; if (messagePathId.ViaLimit == 0) { UIThread.Execute(() => { Windows.Power.Restart(); }); } }, Vm.Seconds, location: this.GetType()); }); }
private void OnPathDisconnected(IMessagePathId pathId) { UIThread.Execute(() => { Vm.PathIds.Remove(pathId); }); }
private void OnPathConnected(IMessagePathId pathId) { UIThread.Execute(() => { Vm.PathIds.Add(pathId); }); }
// 创建管道,将输出通过管道转送到日志文件,然后读取日志文件内容打印到控制台 private static void CreatePipProcess(IMineContext mineContext, string kernelExeFileFullName, string arguments) { SECURITY_ATTRIBUTES saAttr = new SECURITY_ATTRIBUTES { bInheritHandle = true, lpSecurityDescriptor = IntPtr.Zero, length = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES)) }; //set the bInheritHandle flag so pipe handles are inherited saAttr.lpSecurityDescriptor = IntPtr.Zero; //get handle to current stdOut IntPtr mypointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(STARTUPINFO))); Marshal.StructureToPtr(saAttr, mypointer, true); var bret = CreatePipe(out var hReadOut, out var hWriteOut, mypointer, 0); if (!bret) { int lasterr = Marshal.GetLastWin32Error(); VirtualRoot.RaiseEvent(new StartingMineFailedEvent($"管道型进程创建失败 lasterr:{lasterr.ToString()}")); return; } const uint STARTF_USESHOWWINDOW = 0x00000001; const uint STARTF_USESTDHANDLES = 0x00000100; const uint NORMAL_PRIORITY_CLASS = 0x00000020; //const short SW_SHOW = 5; const short SW_HIDE = 0; const int HANDLE_FLAG_INHERIT = 1; //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 }; StringBuilder lpEnvironment = new StringBuilder(); // 复制父进程的环境变量 IDictionary dic = Environment.GetEnvironmentVariables(); // 追加环境变量 foreach (var item in mineContext.CoinKernel.EnvironmentVariables) { dic.Add(item.Key, item.Value); } foreach (var key in dic.Keys) { if (key == null || key.ToString().Contains("\0")) { continue; } var value = dic[key]; if (value == null || value.ToString().Contains("\0")) { continue; } lpEnvironment.Append($"{key.ToString()}={value.ToString()}\0"); } if (CreateProcess( lpApplicationName: null, lpCommandLine: new StringBuilder($"\"{kernelExeFileFullName}\" {arguments}"), lpProcessAttributes: IntPtr.Zero, lpThreadAttributes: IntPtr.Zero, bInheritHandles: true, dwCreationFlags: NORMAL_PRIORITY_CLASS, lpEnvironment: lpEnvironment, lpCurrentDirectory: Path.GetDirectoryName(kernelExeFileFullName), lpStartupInfo: ref lpStartupInfo, lpProcessInformation: out PROCESS_INFORMATION processInfo)) { try { mineContext.KernelProcess = Process.GetProcessById((int)processInfo.dwProcessId); } catch { CloseHandle(hReadOut); VirtualRoot.RaiseEvent(new StartingMineFailedEvent($"内核已退出")); return; } IMessagePathId closeHandle = null; KernelProcessDaemon(mineContext, () => { CloseHandle(hWriteOut); VirtualRoot.DeletePath(closeHandle); }); closeHandle = VirtualRoot.AddOnecePath <MineStopedEvent>("挖矿停止后关闭非托管的日志句柄", LogEnum.DevConsole, action: message => { ReleaseKernelProcessDaemon(mineContext); }, location: typeof(MinerProcess), pathId: Guid.Empty); Task.Factory.StartNew(() => { using (FileStream fs = new FileStream(mineContext.LogFileFullName, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { const byte r = (byte)'\r'; byte[] buffer = new byte[1024]; int ret; // Read会阻塞,直到读取到字符或者hWriteOut被关闭 while ((ret = Read(buffer, 0, buffer.Length, hReadOut)) > 0) { byte[] data = new byte[ret]; int n = 0; for (int i = 0; i < ret; i++) { if (buffer[i] != r) { data[n] = buffer[i]; n++; } } fs.Write(data, 0, n); fs.Flush(); } } CloseHandle(hReadOut); }, TaskCreationOptions.LongRunning); ReadPrintLoopLogFileAsync(mineContext, isWriteToConsole: true); }