예제 #1
0
        private static void UiElement_Closed(object sender, EventArgs e)
        {
            Window uiElement = (Window)sender;
            List <IMessagePathId> messageIds = (List <IMessagePathId>)uiElement.Resources[messagePathIdsResourceKey];

            foreach (var handler in messageIds)
            {
                VirtualRoot.DeletePath(handler);
            }
        }
예제 #2
0
 private static void ReleaseKernelProcessDaemon(IMineContext mineContext)
 {
     if (mineContext.Data.TryGetValue("_kernelProcessDaemon", out object obj))
     {
         VirtualRoot.DeletePath((IMessagePathId)obj);
         mineContext.Data.Remove("_kernelProcessDaemon");
     }
     if (mineContext.Data.TryGetValue("_clear", out obj))
     {
         ((Action)obj)?.Invoke();
         mineContext.Data.Remove("_clear");
     }
 }
            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();
                        }
                    }
                });
            }
예제 #4
0
            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("挖矿内核启动失败,请联系开发人员解决");
                        }
                    }
                });
            }
예제 #5
0
 private void ContextReInit(bool isWork)
 {
     foreach (var handler in _serverContextHandlers)
     {
         VirtualRoot.DeletePath(handler);
     }
     _serverContextHandlers.Clear();
     if (isWork)
     {
         ReInitServerJson();
     }
     ServerContextInit(isWork);
     // CoreContext的视图模型集此时刷新
     VirtualRoot.RaiseEvent(new ServerContextReInitedEvent());
     // CoreContext的视图模型集已全部刷新,此时刷新视图界面
     VirtualRoot.RaiseEvent(new ServerContextVmsReInitedEvent());
     if (isWork)
     {
         // 有可能是由非作业切换为作业,所以需要对IsJsonLocal赋值
         IsJsonLocal = true;
         ReInitMinerProfile();
     }
 }
예제 #6
0
            // 创建管道,将输出通过管道转送到日志文件,然后读取日志文件内容打印到控制台
            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);
                }