private static void Daemon(IMineContext mineContext, Action clear) { string processName = mineContext.Kernel.GetProcessName(); Bus.DelegateHandler <Per1MinuteEvent> daemon = null; daemon = Global.Access <Per1MinuteEvent>( Guid.Parse("a4761e90-dc3c-4483-b055-546084863640"), "周期性检查挖矿内核是否消失,如果消失尝试重启", LogEnum.None, action: message => { if (mineContext == Current.CurrentMineContext) { if (!string.IsNullOrEmpty(processName)) { Process[] processes = Process.GetProcessesByName(processName); if (processes.Length == 0) { mineContext.ProcessDisappearedCound = mineContext.ProcessDisappearedCound + 1; Global.Logger.WarnWriteLine(processName + $"挖矿内核进程消失"); if (Current.MinerProfile.IsAutoRestartKernel && mineContext.ProcessDisappearedCound <= 3) { Global.Logger.WarnWriteLine($"尝试第{mineContext.ProcessDisappearedCound}次重启,共3次"); Current.RestartMine(); Current.CurrentMineContext.ProcessDisappearedCound = mineContext.ProcessDisappearedCound; } else { Current.StopMine(); } Global.UnAccess(daemon); clear?.Invoke(); } } } else { Global.UnAccess(daemon); clear?.Invoke(); } }); }
// 创建管道,将输出通过管道转送到日志文件,然后读取日志文件内容打印到控制台 private static void CreatePipProcess(IMineContext mineContext, string cmdLine) { SECURITY_ATTRIBUTES saAttr = new SECURITY_ATTRIBUTES(); IntPtr hReadOut, hWriteOut; //set the bInheritHandle flag so pipe handles are inherited saAttr.bInheritHandle = true; saAttr.lpSecurityDescriptor = IntPtr.Zero; saAttr.length = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES)); saAttr.lpSecurityDescriptor = IntPtr.Zero; //get handle to current stdOut bool bret; IntPtr mypointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(STARTUPINFO))); Marshal.StructureToPtr(saAttr, mypointer, true); bret = CreatePipe(out hReadOut, out 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 }; PROCESS_INFORMATION lpProcessInformation; if (CreateProcess( lpApplicationName: null, lpCommandLine: new StringBuilder(cmdLine), lpProcessAttributes: IntPtr.Zero, lpThreadAttributes: IntPtr.Zero, bInheritHandles: true, dwCreationFlags: NORMAL_PRIORITY_CLASS, lpEnvironment: IntPtr.Zero, lpCurrentDirectory: null, lpStartupInfo: ref lpStartupInfo, lpProcessInformation: out lpProcessInformation)) { if (bret == false) { int lasterr = Marshal.GetLastWin32Error(); } else { Bus.DelegateHandler <MineStopedEvent> closeHandle = null; bool isHWriteOutHasClosed = false; Daemon(mineContext, () => { if (!isHWriteOutHasClosed) { CloseHandle(hWriteOut); isHWriteOutHasClosed = true; } Global.UnAccess(closeHandle); }); closeHandle = Global.Access <MineStopedEvent>( Guid.Parse("91642027-fd28-4bdd-a05a-31caac6609b1"), "挖矿停止后关闭非托管的日志句柄", LogEnum.Log, action: message => { if (!isHWriteOutHasClosed) { CloseHandle(hWriteOut); isHWriteOutHasClosed = true; } Global.UnAccess(closeHandle); }); string pipLogFileFullName = Path.Combine(SpecialPath.LogsDirFullName, mineContext.PipeFileName); Task.Factory.StartNew(() => { using (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); }); Task.Factory.StartNew(() => { ReadPrintLoopLogFile(mineContext, pipLogFileFullName); }); } } else { Global.Logger.WarnWriteLine("内核启动失败,请重试"); } }