ntminer 6 years ago
parent
commit
f6d3d04b96

+ 2 - 2
src/AppModels/AppContext.cs

@@ -19,7 +19,7 @@ namespace NTMiner {
         /// <summary>
         /// 命令窗口。使用该方法的代码行应将前两个参数放在第一行以方便vs查找引用时展示出参数信息
         /// </summary>
-        private static DelegateHandler<TCmd> Window<TCmd>(string description, LogEnum logType, Action<TCmd> action)
+        public static DelegateHandler<TCmd> Window<TCmd>(string description, LogEnum logType, Action<TCmd> action)
             where TCmd : ICmd {
             return VirtualRoot.Path(description, logType, action).AddToCollection(_contextHandlers);
         }
@@ -27,7 +27,7 @@ namespace NTMiner {
         /// <summary>
         /// 事件响应
         /// </summary>
-        private static DelegateHandler<TEvent> On<TEvent>(string description, LogEnum logType, Action<TEvent> action)
+        public static DelegateHandler<TEvent> On<TEvent>(string description, LogEnum logType, Action<TEvent> action)
             where TEvent : IEvent {
             return VirtualRoot.Path(description, logType, action).AddToCollection(_contextHandlers);
         }

+ 0 - 84
src/AppModels/AppContext.partials.GpuStatusBarViewModel.cs

@@ -1,84 +0,0 @@
-using NTMiner.Vms;
-using System.Linq;
-using System.Windows.Media;
-
-namespace NTMiner {
-    public partial class AppContext {
-        public class GpuStatusBarViewModel : ViewModelBase {
-            public static readonly GpuStatusBarViewModel Instance = new GpuStatusBarViewModel();
-
-            private GpuStatusBarViewModel() {
-#if DEBUG
-                VirtualRoot.Stopwatch.Restart();
-#endif
-                this.GpuAllVm = AppContext.Instance.GpuVms.FirstOrDefault(a => a.Index == NTMinerRoot.GpuAllId);
-#if DEBUG
-                Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {this.GetType().Name}.ctor");
-#endif
-            }
-
-            public GpuViewModel GpuAllVm {
-                get; set;
-            }
-
-            private Geometry _icon;
-            public Geometry Icon {
-                get {
-                    if (_icon == null) {
-                        string iconName;
-                        switch (NTMinerRoot.Instance.GpuSet.GpuType) {
-                            case GpuType.NVIDIA:
-                                iconName = "Icon_Nvidia";
-                                break;
-                            case GpuType.AMD:
-                                iconName = "Icon_AMD";
-                                break;
-                            default:
-                                iconName = "Icon_GpuEmpty";
-                                break;
-                        }
-                        _icon = (Geometry)System.Windows.Application.Current.Resources[iconName];
-                    }
-                    return _icon;
-                }
-            }
-
-            public string IconFill {
-                get {
-                    string iconFill;
-                    switch (NTMinerRoot.Instance.GpuSet.GpuType) {
-                        case GpuType.NVIDIA:
-                            iconFill = "Green";
-                            break;
-                        case GpuType.AMD:
-                            iconFill = "Red";
-                            break;
-                        case GpuType.Empty:
-                        default:
-                            iconFill = "Gray";
-                            break;
-                    }
-                    return iconFill;
-                }
-            }
-
-            public string GpuSetName {
-                get {
-                    return NTMinerRoot.Instance.GpuSet.GpuType.GetDescription();
-                }
-            }
-
-            public string GpuSetInfo {
-                get {
-                    return NTMinerRoot.Instance.GpuSetInfo;
-                }
-            }
-
-            public string GpuCountText {
-                get {
-                    return $"x{NTMinerRoot.Instance.GpuSet.Count}";
-                }
-            }
-        }
-    }
-}

+ 0 - 643
src/AppModels/AppContext.partials.MinerProfileViewModel.cs

@@ -1,643 +0,0 @@
-using NTMiner.Core;
-using NTMiner.MinerServer;
-using NTMiner.Profile;
-using NTMiner.Vms;
-using System;
-using System.Linq;
-using System.Windows.Input;
-
-namespace NTMiner {
-    public partial class AppContext {
-        public class MinerProfileViewModel : ViewModelBase, IMinerProfile {
-            public static readonly MinerProfileViewModel Instance = new MinerProfileViewModel();
-
-            public ICommand AutoStartDelaySecondsUp { get; private set; }
-            public ICommand AutoStartDelaySecondsDown { get; private set; }
-
-            public ICommand AutoRestartKernelTimesUp { get; private set; }
-            public ICommand AutoRestartKernelTimesDown { get; private set; }
-
-            public ICommand NoShareRestartKernelMinutesUp { get; private set; }
-            public ICommand NoShareRestartKernelMinutesDown { get; private set; }
-            public ICommand NoShareRestartComputerMinutesUp { get; private set; }
-            public ICommand NoShareRestartComputerMinutesDown { get; private set; }
-
-            public ICommand PeriodicRestartKernelHoursUp { get; private set; }
-            public ICommand PeriodicRestartKernelHoursDown { get; private set; }
-
-            public ICommand PeriodicRestartKernelMinutesUp { get; private set; }
-            public ICommand PeriodicRestartKernelMinutesDown { get; private set; }
-
-            public ICommand PeriodicRestartComputerHoursUp { get; private set; }
-            public ICommand PeriodicRestartComputerHoursDown { get; private set; }
-
-            public ICommand PeriodicRestartComputerMinutesUp { get; private set; }
-            public ICommand PeriodicRestartComputerMinutesDown { get; private set; }
-
-            public ICommand EPriceUp { get; private set; }
-            public ICommand EPriceDown { get; private set; }
-
-            public ICommand PowerAppendUp { get; private set; }
-            public ICommand PowerAppendDown { get; private set; }
-
-            public ICommand MaxTempUp { get; private set; }
-            public ICommand MaxTempDown { get; private set; }
-
-            public ICommand AutoNoUiMinutesUp { get; private set; }
-            public ICommand AutoNoUiMinutesDown { get; private set; }
-
-            private MinerProfileViewModel() {
-#if DEBUG
-                VirtualRoot.Stopwatch.Restart();
-#endif
-                if (Design.IsInDesignMode) {
-                    return;
-                }
-                this.AutoStartDelaySecondsUp = new DelegateCommand(() => {
-                    this.AutoStartDelaySeconds++;
-                });
-                this.AutoStartDelaySecondsDown = new DelegateCommand(() => {
-                    if (this.AutoStartDelaySeconds > 0) {
-                        this.AutoStartDelaySeconds--;
-                    }
-                });
-                this.AutoRestartKernelTimesUp = new DelegateCommand(() => {
-                    this.AutoRestartKernelTimes++;
-                });
-                this.AutoRestartKernelTimesDown = new DelegateCommand(() => {
-                    if (this.AutoRestartKernelTimes > 0) {
-                        this.AutoRestartKernelTimes--;
-                    }
-                });
-                this.NoShareRestartKernelMinutesUp = new DelegateCommand(() => {
-                    this.NoShareRestartKernelMinutes++;
-                });
-                this.NoShareRestartKernelMinutesDown = new DelegateCommand(() => {
-                    if (this.NoShareRestartKernelMinutes > 0) {
-                        this.NoShareRestartKernelMinutes--;
-                    }
-                });
-                this.NoShareRestartComputerMinutesUp = new DelegateCommand(() => {
-                    this.NoShareRestartComputerMinutes++;
-                });
-                this.NoShareRestartComputerMinutesDown = new DelegateCommand(() => {
-                    if (this.NoShareRestartComputerMinutes > 0) {
-                        this.NoShareRestartComputerMinutes--;
-                    }
-                });
-                this.PeriodicRestartKernelHoursUp = new DelegateCommand(() => {
-                    this.PeriodicRestartKernelHours++;
-                });
-                this.PeriodicRestartKernelHoursDown = new DelegateCommand(() => {
-                    if (this.PeriodicRestartKernelHours > 0) {
-                        this.PeriodicRestartKernelHours--;
-                    }
-                });
-                this.PeriodicRestartKernelMinutesUp = new DelegateCommand(() => {
-                    this.PeriodicRestartKernelMinutes++;
-                });
-                this.PeriodicRestartKernelMinutesDown = new DelegateCommand(() => {
-                    if (this.PeriodicRestartKernelMinutes > 0) {
-                        this.PeriodicRestartKernelMinutes--;
-                    }
-                });
-                this.PeriodicRestartComputerHoursUp = new DelegateCommand(() => {
-                    this.PeriodicRestartComputerHours++;
-                });
-                this.PeriodicRestartComputerHoursDown = new DelegateCommand(() => {
-                    if (this.PeriodicRestartComputerHours > 0) {
-                        this.PeriodicRestartComputerHours--;
-                    }
-                });
-                this.PeriodicRestartComputerMinutesUp = new DelegateCommand(() => {
-                    this.PeriodicRestartComputerMinutes++;
-                });
-                this.PeriodicRestartComputerMinutesDown = new DelegateCommand(() => {
-                    if (this.PeriodicRestartComputerMinutes > 0) {
-                        this.PeriodicRestartComputerMinutes--;
-                    }
-                });
-                this.EPriceUp = new DelegateCommand(() => {
-                    this.EPrice = Math.Round(this.EPrice + 0.1, 2);
-                });
-                this.EPriceDown = new DelegateCommand(() => {
-                    if (this.EPrice > 0.1) {
-                        this.EPrice = Math.Round(this.EPrice - 0.1, 2);
-                    }
-                });
-                this.PowerAppendUp = new DelegateCommand(() => {
-                    this.PowerAppend++;
-                });
-                this.PowerAppendDown = new DelegateCommand(() => {
-                    if (this.PowerAppend > 0) {
-                        this.PowerAppend--;
-                    }
-                });
-                this.MaxTempUp = new DelegateCommand(() => {
-                    this.MaxTemp++;
-                });
-                this.MaxTempDown = new DelegateCommand(() => {
-                    if (this.MaxTemp > 0) {
-                        this.MaxTemp--;
-                    }
-                });
-                this.AutoNoUiMinutesUp = new DelegateCommand(() => {
-                    this.AutoNoUiMinutes++;
-                });
-                this.AutoNoUiMinutesDown = new DelegateCommand(() => {
-                    if (this.AutoNoUiMinutes > 0) {
-                        this.AutoNoUiMinutes--;
-                    }
-                });
-                NTMinerRoot.SetRefreshArgsAssembly(() => {
-                    if (CoinVm != null && CoinVm.CoinKernel != null && CoinVm.CoinKernel.Kernel != null) {
-                        var coinKernelProfile = CoinVm.CoinKernel.CoinKernelProfile;
-                        var kernelInput = CoinVm.CoinKernel.Kernel.KernelInputVm;
-                        if (coinKernelProfile != null && kernelInput != null) {
-                            if (coinKernelProfile.IsDualCoinEnabled && !kernelInput.IsAutoDualWeight) {
-                                if (coinKernelProfile.DualCoinWeight > kernelInput.DualWeightMax) {
-                                    coinKernelProfile.DualCoinWeight = kernelInput.DualWeightMax;
-                                }
-                                else if (coinKernelProfile.DualCoinWeight < kernelInput.DualWeightMin) {
-                                    coinKernelProfile.DualCoinWeight = kernelInput.DualWeightMin;
-                                }
-                                NTMinerRoot.Instance.MinerProfile.SetCoinKernelProfileProperty(coinKernelProfile.CoinKernelId, nameof(coinKernelProfile.DualCoinWeight), coinKernelProfile.DualCoinWeight);
-                            }
-                        }
-                    }
-                    this.ArgsAssembly = NTMinerRoot.Instance.BuildAssembleArgs(out _, out _, out _);
-                });
-                VirtualRoot.On<ServerContextVmsReInitedEvent>("ServerContext的VM集刷新后刷新视图界面", LogEnum.DevConsole,
-                    action: message => {
-                        OnPropertyChanged(nameof(CoinVm));
-                    });
-                Window<RefreshAutoBootStartCommand>("刷新开机启动和自动挖矿的展示", LogEnum.UserConsole,
-                    action: message => {
-                        OnPropertyChanged(nameof(IsAutoBoot));
-                        OnPropertyChanged(nameof(IsAutoStart));
-                    });
-                On<MinerProfilePropertyChangedEvent>("MinerProfile设置变更后刷新VM内存", LogEnum.DevConsole,
-                    action: message => {
-                        OnPropertyChanged(message.PropertyName);
-                    });
-                On<MineWorkPropertyChangedEvent>("MineWork设置变更后刷新VM内存", LogEnum.DevConsole,
-                    action: message => {
-                        OnPropertyChanged(message.PropertyName);
-                    });
-
-                VirtualRoot.On<LocalContextVmsReInitedEvent>("本地上下文视图模型集刷新后刷新界面", LogEnum.DevConsole,
-                    action: message => {
-                        AllPropertyChanged();
-                        if (CoinVm != null) {
-                            CoinVm.OnPropertyChanged(nameof(CoinVm.Wallets));
-                            CoinVm.CoinKernel?.CoinKernelProfile.SelectedDualCoin?.OnPropertyChanged(nameof(CoinVm.Wallets));
-                            CoinVm.CoinProfile.OnPropertyChanged(nameof(CoinVm.CoinProfile.SelectedWallet));
-                            CoinVm.CoinKernel?.CoinKernelProfile.SelectedDualCoin?.CoinProfile.OnPropertyChanged(nameof(CoinVm.CoinProfile.SelectedDualCoinWallet));
-                        }
-                    });
-#if DEBUG
-                Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {this.GetType().Name}.ctor");
-#endif
-            }
-
-            // 是否主矿池和备矿池都是用户名密码模式的矿池
-            public bool IsAllMainCoinPoolIsUserMode {
-                get {
-                    if (CoinVm == null) {
-                        return false;
-                    }
-                    var mainCoinPool = CoinVm.CoinProfile.MainCoinPool;
-                    if (mainCoinPool == null) {
-                        return false;
-                    }
-                    if (mainCoinPool.NoPool1) {
-                        return true;
-                    }
-                    if (CoinVm.CoinKernel.IsSupportPool1) {
-                        var mainCoinPool1 = CoinVm.CoinProfile.MainCoinPool1;
-                        if (mainCoinPool1 == null) {
-                            return mainCoinPool != null && mainCoinPool.IsUserMode;
-                        }
-                        return mainCoinPool != null && mainCoinPool.IsUserMode && mainCoinPool1 != null && mainCoinPool1.IsUserMode;
-                    }
-                    return mainCoinPool != null && mainCoinPool.IsUserMode;
-                }
-            }
-
-            public IMineWork MineWork {
-                get {
-                    return NTMinerRoot.Instance.MinerProfile.MineWork;
-                }
-            }
-
-            public bool IsFreeClient {
-                get {
-                    return MineWork == null || VirtualRoot.IsMinerStudio;
-                }
-            }
-
-            public Guid Id {
-                get { return NTMinerRoot.Instance.MinerProfile.GetId(); }
-            }
-
-            public Guid GetId() {
-                return this.Id;
-            }
-
-            public string MinerName {
-                get {
-                    string minerName = NTMinerRoot.Instance.MinerProfile.MinerName;
-                    // 群控模式时可能未指定群控矿工名,此时使用本地模式交换到注册表的本地矿工名
-                    if (string.IsNullOrEmpty(minerName)) {
-                        return NTMinerRoot.GetMinerName();
-                    }
-                    return minerName;
-                }
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.MinerName != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(MinerName), value);
-                        NTMinerRoot.SetMinerName(value);
-                        NTMinerRoot.RefreshArgsAssembly.Invoke();
-                        OnPropertyChanged(nameof(MinerName));
-                    }
-                }
-            }
-
-            public bool IsShowInTaskbar {
-                get => NTMinerRoot.GetIsShowInTaskbar();
-                set {
-                    if (NTMinerRoot.GetIsShowInTaskbar() != value) {
-                        NTMinerRoot.SetIsShowInTaskbar(value);
-                        OnPropertyChanged(nameof(IsShowInTaskbar));
-                    }
-                }
-            }
-
-            public bool IsNoUi {
-                get { return NTMinerRoot.GetIsNoUi(); }
-                set {
-                    if (NTMinerRoot.GetIsNoUi() != value) {
-                        NTMinerRoot.SetIsNoUi(value);
-                        OnPropertyChanged(nameof(IsNoUi));
-                    }
-                }
-            }
-
-            public bool IsAutoNoUi {
-                get { return NTMinerRoot.GetIsAutoNoUi(); }
-                set {
-                    if (NTMinerRoot.GetIsAutoNoUi() != value) {
-                        NTMinerRoot.SetIsAutoNoUi(value);
-                        OnPropertyChanged(nameof(IsAutoNoUi));
-                    }
-                }
-            }
-
-            public int AutoNoUiMinutes {
-                get { return NTMinerRoot.GetAutoNoUiMinutes(); }
-                set {
-                    if (NTMinerRoot.GetAutoNoUiMinutes() != value) {
-                        NTMinerRoot.SetAutoNoUiMinutes(value);
-                        OnPropertyChanged(nameof(AutoNoUiMinutes));
-                    }
-                }
-            }
-
-            public bool IsShowNotifyIcon {
-                get => NTMinerRoot.GetIsShowNotifyIcon();
-                set {
-                    if (NTMinerRoot.GetIsShowNotifyIcon() != value) {
-                        NTMinerRoot.SetIsShowNotifyIcon(value);
-                        OnPropertyChanged(nameof(IsShowNotifyIcon));
-                        NotifyIcon?.RefreshIcon();
-                    }
-                }
-            }
-
-            public bool IsCloseMeanExit {
-                get => NTMinerRoot.GetIsCloseMeanExit();
-                set {
-                    if (NTMinerRoot.GetIsCloseMeanExit() != value) {
-                        NTMinerRoot.SetIsCloseMeanExit(value);
-                        OnPropertyChanged(nameof(IsCloseMeanExit));
-                    }
-                }
-            }
-
-            public string HotKey {
-                get { return HotKeyUtil.GetHotKey(); }
-                set {
-                    if (HotKeyUtil.GetHotKey() != value) {
-                        if (HotKeyUtil.SetHotKey(value)) {
-                            OnPropertyChanged(nameof(HotKey));
-                        }
-                    }
-                }
-            }
-
-            private string _argsAssembly;
-            private bool _isMining = NTMinerRoot.Instance.IsMining;
-
-            public string ArgsAssembly {
-                get {
-                    return _argsAssembly;
-                }
-                set {
-                    _argsAssembly = value;
-                    OnPropertyChanged(nameof(ArgsAssembly));
-                    NTMinerRoot.UserKernelCommandLine = value;
-                }
-            }
-
-            public bool IsAutoBoot {
-                get => NTMinerRegistry.GetIsAutoBoot();
-                set {
-                    NTMinerRegistry.SetIsAutoBoot(value);
-                    OnPropertyChanged(nameof(IsAutoBoot));
-                }
-            }
-
-            public bool IsAutoStart {
-                get => NTMinerRegistry.GetIsAutoStart();
-                set {
-                    NTMinerRegistry.SetIsAutoStart(value);
-                    OnPropertyChanged(nameof(IsAutoStart));
-                }
-            }
-
-            public bool IsAutoDisableWindowsFirewall {
-                get => NTMinerRegistry.GetIsAutoDisableWindowsFirewall();
-                set {
-                    NTMinerRegistry.SetIsAutoDisableWindowsFirewall(value);
-                    OnPropertyChanged(nameof(IsAutoDisableWindowsFirewall));
-                }
-            }
-
-            public bool IsNoShareRestartKernel {
-                get => NTMinerRoot.Instance.MinerProfile.IsNoShareRestartKernel;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.IsNoShareRestartKernel != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsNoShareRestartKernel), value);
-                        OnPropertyChanged(nameof(IsNoShareRestartKernel));
-                    }
-                }
-            }
-
-            public int NoShareRestartKernelMinutes {
-                get => NTMinerRoot.Instance.MinerProfile.NoShareRestartKernelMinutes;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.NoShareRestartKernelMinutes != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(NoShareRestartKernelMinutes), value);
-                        OnPropertyChanged(nameof(NoShareRestartKernelMinutes));
-                    }
-                }
-            }
-
-            public bool IsNoShareRestartComputer {
-                get => NTMinerRoot.Instance.MinerProfile.IsNoShareRestartComputer;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.IsNoShareRestartComputer != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsNoShareRestartComputer), value);
-                        OnPropertyChanged(nameof(IsNoShareRestartComputer));
-                    }
-                }
-            }
-
-            public int NoShareRestartComputerMinutes {
-                get => NTMinerRoot.Instance.MinerProfile.NoShareRestartComputerMinutes;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.NoShareRestartComputerMinutes != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(NoShareRestartComputerMinutes), value);
-                        OnPropertyChanged(nameof(NoShareRestartComputerMinutes));
-                    }
-                }
-            }
-
-            public bool IsPeriodicRestartKernel {
-                get => NTMinerRoot.Instance.MinerProfile.IsPeriodicRestartKernel;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.IsPeriodicRestartKernel != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsPeriodicRestartKernel), value);
-                        OnPropertyChanged(nameof(IsPeriodicRestartKernel));
-                    }
-                }
-            }
-
-            public int PeriodicRestartKernelHours {
-                get => NTMinerRoot.Instance.MinerProfile.PeriodicRestartKernelHours;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.PeriodicRestartKernelHours != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(PeriodicRestartKernelHours), value);
-                        OnPropertyChanged(nameof(PeriodicRestartKernelHours));
-                    }
-                }
-            }
-
-            public bool IsPeriodicRestartComputer {
-                get => NTMinerRoot.Instance.MinerProfile.IsPeriodicRestartComputer;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.IsPeriodicRestartComputer != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsPeriodicRestartComputer), value);
-                        OnPropertyChanged(nameof(IsPeriodicRestartComputer));
-                    }
-                }
-            }
-
-            public int PeriodicRestartComputerHours {
-                get => NTMinerRoot.Instance.MinerProfile.PeriodicRestartComputerHours;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.PeriodicRestartComputerHours != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(PeriodicRestartComputerHours), value);
-                        OnPropertyChanged(nameof(PeriodicRestartComputerHours));
-                    }
-                }
-            }
-
-            public bool IsAutoRestartKernel {
-                get => NTMinerRoot.Instance.MinerProfile.IsAutoRestartKernel;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.IsAutoRestartKernel != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsAutoRestartKernel), value);
-                        OnPropertyChanged(nameof(IsAutoRestartKernel));
-                    }
-                }
-            }
-
-            public int AutoRestartKernelTimes {
-                get => NTMinerRoot.Instance.MinerProfile.AutoRestartKernelTimes;
-                set {
-                    if (value < 3) {
-                        value = 3;
-                    }
-                    if (NTMinerRoot.Instance.MinerProfile.AutoRestartKernelTimes != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(AutoRestartKernelTimes), value);
-                        OnPropertyChanged(nameof(AutoRestartKernelTimes));
-                    }
-                }
-            }
-
-            public bool IsSpeedDownRestartComputer {
-                get => NTMinerRoot.Instance.MinerProfile.IsSpeedDownRestartComputer;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.IsSpeedDownRestartComputer != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsSpeedDownRestartComputer), value);
-                        OnPropertyChanged(nameof(IsSpeedDownRestartComputer));
-                    }
-                }
-            }
-
-            public int PeriodicRestartKernelMinutes {
-                get => NTMinerRoot.Instance.MinerProfile.PeriodicRestartKernelMinutes;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.PeriodicRestartKernelMinutes != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(PeriodicRestartKernelMinutes), value);
-                        OnPropertyChanged(nameof(PeriodicRestartKernelMinutes));
-                        if (value < 0 || value > 60) {
-                            throw new ValidationException("无效的值");
-                        }
-                    }
-                }
-            }
-
-            public int PeriodicRestartComputerMinutes {
-                get => NTMinerRoot.Instance.MinerProfile.PeriodicRestartComputerMinutes;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.PeriodicRestartComputerMinutes != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(PeriodicRestartComputerMinutes), value);
-                        OnPropertyChanged(nameof(PeriodicRestartComputerMinutes));
-                        if (value < 0 || value > 60) {
-                            throw new ValidationException("无效的值");
-                        }
-                    }
-                }
-            }
-
-            public int RestartComputerSpeedDownPercent {
-                get => NTMinerRoot.Instance.MinerProfile.RestartComputerSpeedDownPercent;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.RestartComputerSpeedDownPercent != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(RestartComputerSpeedDownPercent), value);
-                        OnPropertyChanged(nameof(RestartComputerSpeedDownPercent));
-                    }
-                }
-            }
-
-            public bool IsEChargeEnabled {
-                get => NTMinerRoot.Instance.MinerProfile.IsEChargeEnabled;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.IsEChargeEnabled != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsEChargeEnabled), value);
-                        OnPropertyChanged(nameof(IsEChargeEnabled));
-                    }
-                }
-            }
-
-            public double EPrice {
-                get => NTMinerRoot.Instance.MinerProfile.EPrice;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.EPrice != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(EPrice), value);
-                        OnPropertyChanged(nameof(EPrice));
-                    }
-                }
-            }
-
-            public bool IsPowerAppend {
-                get => NTMinerRoot.Instance.MinerProfile.IsPowerAppend;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.IsPowerAppend != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsPowerAppend), value);
-                        OnPropertyChanged(nameof(IsPowerAppend));
-                    }
-                }
-            }
-
-            public int PowerAppend {
-                get => NTMinerRoot.Instance.MinerProfile.PowerAppend;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.PowerAppend != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(PowerAppend), value);
-                        OnPropertyChanged(nameof(PowerAppend));
-                    }
-                }
-            }
-
-            public bool IsShowCommandLine {
-                get { return NTMinerRoot.GetIsShowCommandLine(); }
-                set {
-                    if (NTMinerRoot.GetIsShowCommandLine() != value) {
-                        NTMinerRoot.SetIsShowCommandLine(value);
-                        OnPropertyChanged(nameof(IsShowCommandLine));
-                    }
-                }
-            }
-
-            public Guid CoinId {
-                get => NTMinerRoot.Instance.MinerProfile.CoinId;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.CoinId != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(CoinId), value);
-                        OnPropertyChanged(nameof(CoinId));
-                    }
-                }
-            }
-
-            public int MaxTemp {
-                get => NTMinerRoot.Instance.MinerProfile.MaxTemp;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.MaxTemp != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(MaxTemp), value);
-                        OnPropertyChanged(nameof(MaxTemp));
-                    }
-                }
-            }
-
-            public int AutoStartDelaySeconds {
-                get => NTMinerRoot.Instance.MinerProfile.AutoStartDelaySeconds;
-                set {
-                    if (NTMinerRoot.Instance.MinerProfile.AutoStartDelaySeconds != value) {
-                        NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(AutoStartDelaySeconds), value);
-                        OnPropertyChanged(nameof(AutoStartDelaySeconds));
-                    }
-                }
-            }
-
-            public CoinViewModel CoinVm {
-                get {
-                    if (!AppContext.Instance.CoinVms.TryGetCoinVm(this.CoinId, out CoinViewModel coinVm) || !coinVm.IsSupported) {
-                        coinVm = AppContext.Instance.CoinVms.MainCoins.Where(a => a.IsSupported).FirstOrDefault();
-                        if (coinVm != null) {
-                            CoinId = coinVm.Id;
-                        }
-                    }
-                    return coinVm;
-                }
-                set {
-                    if (value == null) {
-                        value = AppContext.Instance.CoinVms.MainCoins.Where(a => a.IsSupported).OrderBy(a => a.SortNumber).FirstOrDefault();
-                    }
-                    if (value != null) {
-                        this.CoinId = value.Id;
-                        OnPropertyChanged(nameof(CoinVm));
-                        NTMinerRoot.RefreshArgsAssembly.Invoke();
-                        AppContext.Instance.MinerProfileVm.OnPropertyChanged(nameof(AppContext.Instance.MinerProfileVm.IsAllMainCoinPoolIsUserMode));
-                    }
-                }
-            }
-
-            public bool IsWorker {
-                get {
-                    return MineWork != null && !VirtualRoot.IsMinerStudio;
-                }
-            }
-
-            public bool IsMining {
-                get => _isMining;
-                set {
-                    _isMining = value;
-                    OnPropertyChanged(nameof(IsMining));
-                }
-            }
-        }
-    }
-}

+ 0 - 72
src/AppModels/AppContext.partials.StartStopMineButtonViewModel.cs

@@ -1,72 +0,0 @@
-using NTMiner.Vms;
-using System.Windows.Input;
-
-namespace NTMiner {
-    public partial class AppContext {
-        public class StartStopMineButtonViewModel : ViewModelBase {
-            public static readonly StartStopMineButtonViewModel Instance = new StartStopMineButtonViewModel();
-
-            public ICommand StartMine { get; private set; }
-            public ICommand StopMine { get; private set; }
-
-            private StartStopMineButtonViewModel() {
-                if (Design.IsInDesignMode) {
-                    return;
-                }
-#if DEBUG
-                VirtualRoot.Stopwatch.Restart();
-#endif
-                this.StartMine = new DelegateCommand(() => {
-                    this.MinerProfile.IsMining = true;
-                    NTMinerRoot.Instance.StartMine();
-                    BtnStopText = "正在挖矿";
-                });
-                this.StopMine = new DelegateCommand(() => {
-                    if (!NTMinerRoot.Instance.IsMining) {
-                        this.MinerProfile.IsMining = false;
-                    }
-                    NTMinerRoot.IsAutoStartCanceled = true;
-                    NTMinerRoot.Instance.StopMineAsync(()=> {
-                        if (!NTMinerRoot.Instance.IsMining) {
-                            this.MinerProfile.IsMining = false;
-                        }
-                    });
-                });
-                if (NTMinerRoot.IsAutoStart && !this.MinerProfile.IsMining && VirtualRoot.SecondCount < MinerProfile.AutoStartDelaySeconds) {
-                    this.MinerProfile.IsMining = true;
-                    int n = MinerProfile.AutoStartDelaySeconds;
-                    Bus.IDelegateHandler handler = null;
-                    handler = On<Per1SecondEvent>("挖矿倒计时", LogEnum.None,
-                    action: message => {
-                        BtnStopText = $"倒计时({--n})";
-                        if (n <= 0) {
-                            BtnStopText = "正在挖矿";
-                            VirtualRoot.UnPath(handler);
-                            if (!NTMinerRoot.IsAutoStartCanceled) {
-                                NTMinerRoot.Instance.StartMine();
-                            }
-                        }
-                    });
-                }
-#if DEBUG
-                Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {this.GetType().Name}.ctor");
-#endif
-            }
-
-            private string _btnStopText = "正在挖矿";
-            public string BtnStopText {
-                get => _btnStopText;
-                set {
-                    _btnStopText = value;
-                    OnPropertyChanged(nameof(BtnStopText));
-                }
-            }
-
-            public MinerProfileViewModel MinerProfile {
-                get {
-                    return AppContext.Instance.MinerProfileVm;
-                }
-            }
-        }
-    }
-}

+ 0 - 146
src/AppModels/AppContext.partials.VirtualMemorySetViewModel.cs

@@ -1,146 +0,0 @@
-using Microsoft.Win32;
-using NTMiner.Vms;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace NTMiner {
-    public partial class AppContext {
-        public class VirtualMemorySetViewModel : ViewModelBase, IEnumerable<VirtualMemoryViewModel> {
-            public static readonly VirtualMemorySetViewModel Instance = new VirtualMemorySetViewModel();
-
-            private readonly Dictionary<string, VirtualMemoryViewModel> _dic = new Dictionary<string, VirtualMemoryViewModel>(StringComparer.OrdinalIgnoreCase);
-
-            private readonly Dictionary<string, VirtualMemoryViewModel> _initialVms = new Dictionary<string, VirtualMemoryViewModel>(StringComparer.OrdinalIgnoreCase);
-            private VirtualMemorySetViewModel() {
-#if DEBUG
-                VirtualRoot.Stopwatch.Restart();
-#endif
-                foreach (var item in GetPagingFiles()) {
-                    _initialVms.Add(item.DriveName, item);
-                }
-                foreach (var drive in AppContext.Instance.DriveSetVm.Drives) {
-                    _dic.Add(drive.Name, new VirtualMemoryViewModel(drive.Name, 0));
-                }
-                foreach (var item in _initialVms.Values) {
-                    if (_dic.TryGetValue(item.DriveName, out VirtualMemoryViewModel vm)) {
-                        vm.MaxSizeMb = item.MaxSizeMb;
-                    }
-                }
-                NTMinerRoot.OSVirtualMemoryMb = _dic.Values.Sum(a => a.MaxSizeMb);
-#if DEBUG
-                Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {this.GetType().Name}.ctor");
-#endif
-            }
-
-            public bool IsStateChanged {
-                get {
-                    foreach (var item in _dic.Values.Where(a => a.MaxSizeMb != 0)) {
-                        if (!_initialVms.ContainsKey(item.DriveName)) {
-                            return true;
-                        }
-                    }
-                    foreach (var item in _initialVms) {
-                        if (_dic[item.Key].MaxSizeB != item.Value.MaxSizeB) {
-                            return true;
-                        }
-                    }
-                    return false;
-                }
-            }
-
-
-            public int TotalVirtualMemoryGb {
-                get {
-                    return _dic.Values.Sum(a => a.MaxSizeGb);
-                }
-            }
-
-            public string TotalVirtualMemoryGbText {
-                get {
-                    return TotalVirtualMemoryGb + " G";
-                }
-            }
-
-            private const string MemoryManagementSubKey = @"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management";
-            public void SetVirtualMemoryOfDrive() {
-                List<VirtualMemoryViewModel> virtualMemories = _dic.Values.Where(a => a.MaxSizeMb != 0).ToList();
-                string[] value = virtualMemories.Select(a => a.ToString()).ToArray();
-
-                Windows.WinRegistry.SetValue(Registry.LocalMachine, MemoryManagementSubKey, "PagingFiles", value);
-                OnPropertyChanged(nameof(TotalVirtualMemoryGb));
-                OnPropertyChanged(nameof(TotalVirtualMemoryGbText));
-                OnPropertyChanged(nameof(IsStateChanged));
-                NTMinerRoot.OSVirtualMemoryMb = _dic.Values.Sum(a => a.MaxSizeMb);
-            }
-
-            private List<VirtualMemoryViewModel> GetPagingFiles() {
-                object value = Windows.WinRegistry.GetValue(Registry.LocalMachine, MemoryManagementSubKey, "PagingFiles");
-                // REG_SZ or REG_MULTI_SZ
-                List<VirtualMemoryViewModel> list;
-                if (value is string[]) {
-                    list = Parse((string[])value);
-                }
-                else {
-                    list = new List<VirtualMemoryViewModel>();
-                }
-                return list;
-            }
-
-            private VirtualMemoryViewModel Parse(string vmReg) {
-                string driveName;
-                int minsize = 0;
-                int maxsize = 0;
-                try {
-                    string[] strarr = vmReg.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
-                    if (strarr.Length == 3) {
-                        driveName = strarr[0].Substring(0, 3);
-                        minsize = Convert.ToInt32(strarr[1]);
-                        maxsize = Convert.ToInt32(strarr[2]);
-                        return new VirtualMemoryViewModel(driveName, maxsize);
-                    }
-                    return null;
-                }
-                catch (Exception e) {
-                    Logger.ErrorDebugLine(e);
-                    return null;
-                }
-            }
-
-            private List<VirtualMemoryViewModel> Parse(string[] vmReg) {
-                List<VirtualMemoryViewModel> list = new List<VirtualMemoryViewModel>();
-                try {
-                    foreach (string item in vmReg) {
-                        VirtualMemoryViewModel vm = Parse(item);
-                        if (vm != null) {
-                            list.Add(vm);
-                        }
-                    }
-                }
-                catch (Exception e) {
-                    Logger.ErrorDebugLine(e);
-                }
-                return list;
-            }
-
-            public VirtualMemoryViewModel this[string driveName] {
-                get {
-                    return _dic[driveName];
-                }
-            }
-
-            public bool Contains(string driveName) {
-                return _dic.ContainsKey(driveName);
-            }
-
-            public IEnumerator<VirtualMemoryViewModel> GetEnumerator() {
-                return _dic.Values.GetEnumerator();
-            }
-
-            IEnumerator IEnumerable.GetEnumerator() {
-                return _dic.Values.GetEnumerator();
-            }
-        }
-    }
-}

+ 4 - 4
src/AppModels/AppModels.csproj

@@ -64,7 +64,6 @@
     <Compile Include="AppContext.partials.FileWriterViewModels.cs" />
     <Compile Include="AppContext.partials.GpuProfileViewModels.cs" />
     <Compile Include="AppContext.partials.GpuSpeedViewModels.cs" />
-    <Compile Include="AppContext.partials.GpuStatusBarViewModel.cs" />
     <Compile Include="AppContext.partials.GpuViewModels.cs" />
     <Compile Include="AppContext.partials.GroupViewModels.cs" />
     <Compile Include="AppContext.partials.KernelInputViewModels.cs" />
@@ -73,7 +72,6 @@
     <Compile Include="AppContext.partials.KernelOutputViewModels.cs" />
     <Compile Include="AppContext.partials.KernelViewModels.cs" />
     <Compile Include="AppContext.partials.MinerGroupViewModels.cs" />
-    <Compile Include="AppContext.partials.MinerProfileViewModel.cs" />
     <Compile Include="AppContext.partials.MineWorkViewModels.cs" />
     <Compile Include="AppContext.partials.OverClockDataViewModels.cs" />
     <Compile Include="AppContext.partials.PackageViewModels.cs" />
@@ -81,11 +79,9 @@
     <Compile Include="AppContext.partials.PoolProfileViewModels.cs" />
     <Compile Include="AppContext.partials.PoolViewModels.cs" />
     <Compile Include="AppContext.partials.ShareViewModels.cs" />
-    <Compile Include="AppContext.partials.StartStopMineButtonViewModel.cs" />
     <Compile Include="AppContext.partials.SysDicItemViewModels.cs" />
     <Compile Include="AppContext.partials.SysDicViewModels.cs" />
     <Compile Include="AppContext.partials.UserViewModels.cs" />
-    <Compile Include="AppContext.partials.VirtualMemorySetViewModel.cs" />
     <Compile Include="AppContext.partials.WalletViewModels.cs" />
     <Compile Include="AppStatic.cs" />
     <Compile Include="ExtendedNotifyIcon.cs" />
@@ -114,9 +110,12 @@
     <Compile Include="Vms\FragmentWriterSelectViewModel.cs" />
     <Compile Include="Vms\FileWriterSelectViewModel.cs" />
     <Compile Include="Vms\FragmentWriterViewModel.cs" />
+    <Compile Include="Vms\GpuStatusBarViewModel.cs" />
     <Compile Include="Vms\HandlerIdsWindowViewModel.cs" />
     <Compile Include="Vms\KernelOutputSelectViewModel.cs" />
     <Compile Include="Vms\KernelInputSelectViewModel.cs" />
+    <Compile Include="Vms\MinerProfileViewModel.cs" />
+    <Compile Include="Vms\StartStopMineButtonViewModel.cs" />
     <Compile Include="Vms\SysDicItemSelectViewModel.cs" />
     <Compile Include="Vms\CoinSelectViewModel.cs" />
     <Compile Include="Vms\CoinSnapshotDataViewModel.cs" />
@@ -195,6 +194,7 @@
     <Compile Include="Vms\ToolboxViewModel.cs" />
     <Compile Include="Vms\UserPageViewModel.cs" />
     <Compile Include="Vms\UserViewModel.cs" />
+    <Compile Include="Vms\VirtualMemorySetViewModel.cs" />
     <Compile Include="Vms\VirtualMemoryViewModel.cs" />
     <Compile Include="Vms\WalletSelectViewModel.cs" />
     <Compile Include="Vms\WalletViewModel.cs" />

+ 1 - 1
src/AppModels/Vms/CoinPageViewModel.cs

@@ -36,7 +36,7 @@ namespace NTMiner.Vms {
             }
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }

+ 1 - 1
src/AppModels/Vms/ConsoleViewModel.cs

@@ -3,7 +3,7 @@
         public ConsoleViewModel() {
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }

+ 81 - 0
src/AppModels/Vms/GpuStatusBarViewModel.cs

@@ -0,0 +1,81 @@
+using System.Linq;
+using System.Windows.Media;
+
+namespace NTMiner.Vms {
+    public class GpuStatusBarViewModel : ViewModelBase {
+        public static readonly GpuStatusBarViewModel Instance = new GpuStatusBarViewModel();
+
+        private GpuStatusBarViewModel() {
+#if DEBUG
+                VirtualRoot.Stopwatch.Restart();
+#endif
+            this.GpuAllVm = AppContext.Instance.GpuVms.FirstOrDefault(a => a.Index == NTMinerRoot.GpuAllId);
+#if DEBUG
+                Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {this.GetType().Name}.ctor");
+#endif
+        }
+
+        public GpuViewModel GpuAllVm {
+            get; set;
+        }
+
+        private Geometry _icon;
+        public Geometry Icon {
+            get {
+                if (_icon == null) {
+                    string iconName;
+                    switch (NTMinerRoot.Instance.GpuSet.GpuType) {
+                        case GpuType.NVIDIA:
+                            iconName = "Icon_Nvidia";
+                            break;
+                        case GpuType.AMD:
+                            iconName = "Icon_AMD";
+                            break;
+                        default:
+                            iconName = "Icon_GpuEmpty";
+                            break;
+                    }
+                    _icon = (Geometry)System.Windows.Application.Current.Resources[iconName];
+                }
+                return _icon;
+            }
+        }
+
+        public string IconFill {
+            get {
+                string iconFill;
+                switch (NTMinerRoot.Instance.GpuSet.GpuType) {
+                    case GpuType.NVIDIA:
+                        iconFill = "Green";
+                        break;
+                    case GpuType.AMD:
+                        iconFill = "Red";
+                        break;
+                    case GpuType.Empty:
+                    default:
+                        iconFill = "Gray";
+                        break;
+                }
+                return iconFill;
+            }
+        }
+
+        public string GpuSetName {
+            get {
+                return NTMinerRoot.Instance.GpuSet.GpuType.GetDescription();
+            }
+        }
+
+        public string GpuSetInfo {
+            get {
+                return NTMinerRoot.Instance.GpuSetInfo;
+            }
+        }
+
+        public string GpuCountText {
+            get {
+                return $"x{NTMinerRoot.Instance.GpuSet.Count}";
+            }
+        }
+    }
+}

+ 1 - 1
src/AppModels/Vms/KernelsWindowViewModel.cs

@@ -121,7 +121,7 @@ namespace NTMiner.Vms {
             }
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }

+ 1 - 1
src/AppModels/Vms/LogColorViewModel.cs

@@ -10,7 +10,7 @@ namespace NTMiner.Vms {
 
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }

+ 1 - 1
src/AppModels/Vms/MainWindowViewModel.cs

@@ -87,7 +87,7 @@ namespace NTMiner.Vms {
             }
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }

+ 1 - 1
src/AppModels/Vms/MineWorkViewModel.cs

@@ -177,7 +177,7 @@ namespace NTMiner.Vms {
             }
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }

+ 1 - 1
src/AppModels/Vms/MinerProfileIndexViewModel.cs

@@ -6,7 +6,7 @@ namespace NTMiner.Vms {
         public MinerProfileIndexViewModel() {
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }

+ 640 - 0
src/AppModels/Vms/MinerProfileViewModel.cs

@@ -0,0 +1,640 @@
+using NTMiner.Core;
+using NTMiner.MinerServer;
+using NTMiner.Profile;
+using System;
+using System.Linq;
+using System.Windows.Input;
+
+namespace NTMiner.Vms {
+    public class MinerProfileViewModel : ViewModelBase, IMinerProfile {
+        public static readonly MinerProfileViewModel Instance = new MinerProfileViewModel();
+
+        public ICommand AutoStartDelaySecondsUp { get; private set; }
+        public ICommand AutoStartDelaySecondsDown { get; private set; }
+
+        public ICommand AutoRestartKernelTimesUp { get; private set; }
+        public ICommand AutoRestartKernelTimesDown { get; private set; }
+
+        public ICommand NoShareRestartKernelMinutesUp { get; private set; }
+        public ICommand NoShareRestartKernelMinutesDown { get; private set; }
+        public ICommand NoShareRestartComputerMinutesUp { get; private set; }
+        public ICommand NoShareRestartComputerMinutesDown { get; private set; }
+
+        public ICommand PeriodicRestartKernelHoursUp { get; private set; }
+        public ICommand PeriodicRestartKernelHoursDown { get; private set; }
+
+        public ICommand PeriodicRestartKernelMinutesUp { get; private set; }
+        public ICommand PeriodicRestartKernelMinutesDown { get; private set; }
+
+        public ICommand PeriodicRestartComputerHoursUp { get; private set; }
+        public ICommand PeriodicRestartComputerHoursDown { get; private set; }
+
+        public ICommand PeriodicRestartComputerMinutesUp { get; private set; }
+        public ICommand PeriodicRestartComputerMinutesDown { get; private set; }
+
+        public ICommand EPriceUp { get; private set; }
+        public ICommand EPriceDown { get; private set; }
+
+        public ICommand PowerAppendUp { get; private set; }
+        public ICommand PowerAppendDown { get; private set; }
+
+        public ICommand MaxTempUp { get; private set; }
+        public ICommand MaxTempDown { get; private set; }
+
+        public ICommand AutoNoUiMinutesUp { get; private set; }
+        public ICommand AutoNoUiMinutesDown { get; private set; }
+
+        private MinerProfileViewModel() {
+#if DEBUG
+                VirtualRoot.Stopwatch.Restart();
+#endif
+            if (Design.IsInDesignMode) {
+                return;
+            }
+            this.AutoStartDelaySecondsUp = new DelegateCommand(() => {
+                this.AutoStartDelaySeconds++;
+            });
+            this.AutoStartDelaySecondsDown = new DelegateCommand(() => {
+                if (this.AutoStartDelaySeconds > 0) {
+                    this.AutoStartDelaySeconds--;
+                }
+            });
+            this.AutoRestartKernelTimesUp = new DelegateCommand(() => {
+                this.AutoRestartKernelTimes++;
+            });
+            this.AutoRestartKernelTimesDown = new DelegateCommand(() => {
+                if (this.AutoRestartKernelTimes > 0) {
+                    this.AutoRestartKernelTimes--;
+                }
+            });
+            this.NoShareRestartKernelMinutesUp = new DelegateCommand(() => {
+                this.NoShareRestartKernelMinutes++;
+            });
+            this.NoShareRestartKernelMinutesDown = new DelegateCommand(() => {
+                if (this.NoShareRestartKernelMinutes > 0) {
+                    this.NoShareRestartKernelMinutes--;
+                }
+            });
+            this.NoShareRestartComputerMinutesUp = new DelegateCommand(() => {
+                this.NoShareRestartComputerMinutes++;
+            });
+            this.NoShareRestartComputerMinutesDown = new DelegateCommand(() => {
+                if (this.NoShareRestartComputerMinutes > 0) {
+                    this.NoShareRestartComputerMinutes--;
+                }
+            });
+            this.PeriodicRestartKernelHoursUp = new DelegateCommand(() => {
+                this.PeriodicRestartKernelHours++;
+            });
+            this.PeriodicRestartKernelHoursDown = new DelegateCommand(() => {
+                if (this.PeriodicRestartKernelHours > 0) {
+                    this.PeriodicRestartKernelHours--;
+                }
+            });
+            this.PeriodicRestartKernelMinutesUp = new DelegateCommand(() => {
+                this.PeriodicRestartKernelMinutes++;
+            });
+            this.PeriodicRestartKernelMinutesDown = new DelegateCommand(() => {
+                if (this.PeriodicRestartKernelMinutes > 0) {
+                    this.PeriodicRestartKernelMinutes--;
+                }
+            });
+            this.PeriodicRestartComputerHoursUp = new DelegateCommand(() => {
+                this.PeriodicRestartComputerHours++;
+            });
+            this.PeriodicRestartComputerHoursDown = new DelegateCommand(() => {
+                if (this.PeriodicRestartComputerHours > 0) {
+                    this.PeriodicRestartComputerHours--;
+                }
+            });
+            this.PeriodicRestartComputerMinutesUp = new DelegateCommand(() => {
+                this.PeriodicRestartComputerMinutes++;
+            });
+            this.PeriodicRestartComputerMinutesDown = new DelegateCommand(() => {
+                if (this.PeriodicRestartComputerMinutes > 0) {
+                    this.PeriodicRestartComputerMinutes--;
+                }
+            });
+            this.EPriceUp = new DelegateCommand(() => {
+                this.EPrice = Math.Round(this.EPrice + 0.1, 2);
+            });
+            this.EPriceDown = new DelegateCommand(() => {
+                if (this.EPrice > 0.1) {
+                    this.EPrice = Math.Round(this.EPrice - 0.1, 2);
+                }
+            });
+            this.PowerAppendUp = new DelegateCommand(() => {
+                this.PowerAppend++;
+            });
+            this.PowerAppendDown = new DelegateCommand(() => {
+                if (this.PowerAppend > 0) {
+                    this.PowerAppend--;
+                }
+            });
+            this.MaxTempUp = new DelegateCommand(() => {
+                this.MaxTemp++;
+            });
+            this.MaxTempDown = new DelegateCommand(() => {
+                if (this.MaxTemp > 0) {
+                    this.MaxTemp--;
+                }
+            });
+            this.AutoNoUiMinutesUp = new DelegateCommand(() => {
+                this.AutoNoUiMinutes++;
+            });
+            this.AutoNoUiMinutesDown = new DelegateCommand(() => {
+                if (this.AutoNoUiMinutes > 0) {
+                    this.AutoNoUiMinutes--;
+                }
+            });
+            NTMinerRoot.SetRefreshArgsAssembly(() => {
+                if (CoinVm != null && CoinVm.CoinKernel != null && CoinVm.CoinKernel.Kernel != null) {
+                    var coinKernelProfile = CoinVm.CoinKernel.CoinKernelProfile;
+                    var kernelInput = CoinVm.CoinKernel.Kernel.KernelInputVm;
+                    if (coinKernelProfile != null && kernelInput != null) {
+                        if (coinKernelProfile.IsDualCoinEnabled && !kernelInput.IsAutoDualWeight) {
+                            if (coinKernelProfile.DualCoinWeight > kernelInput.DualWeightMax) {
+                                coinKernelProfile.DualCoinWeight = kernelInput.DualWeightMax;
+                            }
+                            else if (coinKernelProfile.DualCoinWeight < kernelInput.DualWeightMin) {
+                                coinKernelProfile.DualCoinWeight = kernelInput.DualWeightMin;
+                            }
+                            NTMinerRoot.Instance.MinerProfile.SetCoinKernelProfileProperty(coinKernelProfile.CoinKernelId, nameof(coinKernelProfile.DualCoinWeight), coinKernelProfile.DualCoinWeight);
+                        }
+                    }
+                }
+                this.ArgsAssembly = NTMinerRoot.Instance.BuildAssembleArgs(out _, out _, out _);
+            });
+            VirtualRoot.On<ServerContextVmsReInitedEvent>("ServerContext的VM集刷新后刷新视图界面", LogEnum.DevConsole,
+                action: message => {
+                    OnPropertyChanged(nameof(CoinVm));
+                });
+            AppContext.Window<RefreshAutoBootStartCommand>("刷新开机启动和自动挖矿的展示", LogEnum.UserConsole,
+                action: message => {
+                    OnPropertyChanged(nameof(IsAutoBoot));
+                    OnPropertyChanged(nameof(IsAutoStart));
+                });
+            AppContext.On<MinerProfilePropertyChangedEvent>("MinerProfile设置变更后刷新VM内存", LogEnum.DevConsole,
+                action: message => {
+                    OnPropertyChanged(message.PropertyName);
+                });
+            AppContext.On<MineWorkPropertyChangedEvent>("MineWork设置变更后刷新VM内存", LogEnum.DevConsole,
+                action: message => {
+                    OnPropertyChanged(message.PropertyName);
+                });
+
+            VirtualRoot.On<LocalContextVmsReInitedEvent>("本地上下文视图模型集刷新后刷新界面", LogEnum.DevConsole,
+                action: message => {
+                    AllPropertyChanged();
+                    if (CoinVm != null) {
+                        CoinVm.OnPropertyChanged(nameof(CoinVm.Wallets));
+                        CoinVm.CoinKernel?.CoinKernelProfile.SelectedDualCoin?.OnPropertyChanged(nameof(CoinVm.Wallets));
+                        CoinVm.CoinProfile.OnPropertyChanged(nameof(CoinVm.CoinProfile.SelectedWallet));
+                        CoinVm.CoinKernel?.CoinKernelProfile.SelectedDualCoin?.CoinProfile.OnPropertyChanged(nameof(CoinVm.CoinProfile.SelectedDualCoinWallet));
+                    }
+                });
+#if DEBUG
+                Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {this.GetType().Name}.ctor");
+#endif
+        }
+
+        // 是否主矿池和备矿池都是用户名密码模式的矿池
+        public bool IsAllMainCoinPoolIsUserMode {
+            get {
+                if (CoinVm == null) {
+                    return false;
+                }
+                var mainCoinPool = CoinVm.CoinProfile.MainCoinPool;
+                if (mainCoinPool == null) {
+                    return false;
+                }
+                if (mainCoinPool.NoPool1) {
+                    return true;
+                }
+                if (CoinVm.CoinKernel.IsSupportPool1) {
+                    var mainCoinPool1 = CoinVm.CoinProfile.MainCoinPool1;
+                    if (mainCoinPool1 == null) {
+                        return mainCoinPool != null && mainCoinPool.IsUserMode;
+                    }
+                    return mainCoinPool != null && mainCoinPool.IsUserMode && mainCoinPool1 != null && mainCoinPool1.IsUserMode;
+                }
+                return mainCoinPool != null && mainCoinPool.IsUserMode;
+            }
+        }
+
+        public IMineWork MineWork {
+            get {
+                return NTMinerRoot.Instance.MinerProfile.MineWork;
+            }
+        }
+
+        public bool IsFreeClient {
+            get {
+                return MineWork == null || VirtualRoot.IsMinerStudio;
+            }
+        }
+
+        public Guid Id {
+            get { return NTMinerRoot.Instance.MinerProfile.GetId(); }
+        }
+
+        public Guid GetId() {
+            return this.Id;
+        }
+
+        public string MinerName {
+            get {
+                string minerName = NTMinerRoot.Instance.MinerProfile.MinerName;
+                // 群控模式时可能未指定群控矿工名,此时使用本地模式交换到注册表的本地矿工名
+                if (string.IsNullOrEmpty(minerName)) {
+                    return NTMinerRoot.GetMinerName();
+                }
+                return minerName;
+            }
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.MinerName != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(MinerName), value);
+                    NTMinerRoot.SetMinerName(value);
+                    NTMinerRoot.RefreshArgsAssembly.Invoke();
+                    OnPropertyChanged(nameof(MinerName));
+                }
+            }
+        }
+
+        public bool IsShowInTaskbar {
+            get => NTMinerRoot.GetIsShowInTaskbar();
+            set {
+                if (NTMinerRoot.GetIsShowInTaskbar() != value) {
+                    NTMinerRoot.SetIsShowInTaskbar(value);
+                    OnPropertyChanged(nameof(IsShowInTaskbar));
+                }
+            }
+        }
+
+        public bool IsNoUi {
+            get { return NTMinerRoot.GetIsNoUi(); }
+            set {
+                if (NTMinerRoot.GetIsNoUi() != value) {
+                    NTMinerRoot.SetIsNoUi(value);
+                    OnPropertyChanged(nameof(IsNoUi));
+                }
+            }
+        }
+
+        public bool IsAutoNoUi {
+            get { return NTMinerRoot.GetIsAutoNoUi(); }
+            set {
+                if (NTMinerRoot.GetIsAutoNoUi() != value) {
+                    NTMinerRoot.SetIsAutoNoUi(value);
+                    OnPropertyChanged(nameof(IsAutoNoUi));
+                }
+            }
+        }
+
+        public int AutoNoUiMinutes {
+            get { return NTMinerRoot.GetAutoNoUiMinutes(); }
+            set {
+                if (NTMinerRoot.GetAutoNoUiMinutes() != value) {
+                    NTMinerRoot.SetAutoNoUiMinutes(value);
+                    OnPropertyChanged(nameof(AutoNoUiMinutes));
+                }
+            }
+        }
+
+        public bool IsShowNotifyIcon {
+            get => NTMinerRoot.GetIsShowNotifyIcon();
+            set {
+                if (NTMinerRoot.GetIsShowNotifyIcon() != value) {
+                    NTMinerRoot.SetIsShowNotifyIcon(value);
+                    OnPropertyChanged(nameof(IsShowNotifyIcon));
+                    AppContext.NotifyIcon?.RefreshIcon();
+                }
+            }
+        }
+
+        public bool IsCloseMeanExit {
+            get => NTMinerRoot.GetIsCloseMeanExit();
+            set {
+                if (NTMinerRoot.GetIsCloseMeanExit() != value) {
+                    NTMinerRoot.SetIsCloseMeanExit(value);
+                    OnPropertyChanged(nameof(IsCloseMeanExit));
+                }
+            }
+        }
+
+        public string HotKey {
+            get { return HotKeyUtil.GetHotKey(); }
+            set {
+                if (HotKeyUtil.GetHotKey() != value) {
+                    if (HotKeyUtil.SetHotKey(value)) {
+                        OnPropertyChanged(nameof(HotKey));
+                    }
+                }
+            }
+        }
+
+        private string _argsAssembly;
+        private bool _isMining = NTMinerRoot.Instance.IsMining;
+
+        public string ArgsAssembly {
+            get {
+                return _argsAssembly;
+            }
+            set {
+                _argsAssembly = value;
+                OnPropertyChanged(nameof(ArgsAssembly));
+                NTMinerRoot.UserKernelCommandLine = value;
+            }
+        }
+
+        public bool IsAutoBoot {
+            get => NTMinerRegistry.GetIsAutoBoot();
+            set {
+                NTMinerRegistry.SetIsAutoBoot(value);
+                OnPropertyChanged(nameof(IsAutoBoot));
+            }
+        }
+
+        public bool IsAutoStart {
+            get => NTMinerRegistry.GetIsAutoStart();
+            set {
+                NTMinerRegistry.SetIsAutoStart(value);
+                OnPropertyChanged(nameof(IsAutoStart));
+            }
+        }
+
+        public bool IsAutoDisableWindowsFirewall {
+            get => NTMinerRegistry.GetIsAutoDisableWindowsFirewall();
+            set {
+                NTMinerRegistry.SetIsAutoDisableWindowsFirewall(value);
+                OnPropertyChanged(nameof(IsAutoDisableWindowsFirewall));
+            }
+        }
+
+        public bool IsNoShareRestartKernel {
+            get => NTMinerRoot.Instance.MinerProfile.IsNoShareRestartKernel;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.IsNoShareRestartKernel != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsNoShareRestartKernel), value);
+                    OnPropertyChanged(nameof(IsNoShareRestartKernel));
+                }
+            }
+        }
+
+        public int NoShareRestartKernelMinutes {
+            get => NTMinerRoot.Instance.MinerProfile.NoShareRestartKernelMinutes;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.NoShareRestartKernelMinutes != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(NoShareRestartKernelMinutes), value);
+                    OnPropertyChanged(nameof(NoShareRestartKernelMinutes));
+                }
+            }
+        }
+
+        public bool IsNoShareRestartComputer {
+            get => NTMinerRoot.Instance.MinerProfile.IsNoShareRestartComputer;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.IsNoShareRestartComputer != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsNoShareRestartComputer), value);
+                    OnPropertyChanged(nameof(IsNoShareRestartComputer));
+                }
+            }
+        }
+
+        public int NoShareRestartComputerMinutes {
+            get => NTMinerRoot.Instance.MinerProfile.NoShareRestartComputerMinutes;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.NoShareRestartComputerMinutes != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(NoShareRestartComputerMinutes), value);
+                    OnPropertyChanged(nameof(NoShareRestartComputerMinutes));
+                }
+            }
+        }
+
+        public bool IsPeriodicRestartKernel {
+            get => NTMinerRoot.Instance.MinerProfile.IsPeriodicRestartKernel;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.IsPeriodicRestartKernel != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsPeriodicRestartKernel), value);
+                    OnPropertyChanged(nameof(IsPeriodicRestartKernel));
+                }
+            }
+        }
+
+        public int PeriodicRestartKernelHours {
+            get => NTMinerRoot.Instance.MinerProfile.PeriodicRestartKernelHours;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.PeriodicRestartKernelHours != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(PeriodicRestartKernelHours), value);
+                    OnPropertyChanged(nameof(PeriodicRestartKernelHours));
+                }
+            }
+        }
+
+        public bool IsPeriodicRestartComputer {
+            get => NTMinerRoot.Instance.MinerProfile.IsPeriodicRestartComputer;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.IsPeriodicRestartComputer != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsPeriodicRestartComputer), value);
+                    OnPropertyChanged(nameof(IsPeriodicRestartComputer));
+                }
+            }
+        }
+
+        public int PeriodicRestartComputerHours {
+            get => NTMinerRoot.Instance.MinerProfile.PeriodicRestartComputerHours;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.PeriodicRestartComputerHours != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(PeriodicRestartComputerHours), value);
+                    OnPropertyChanged(nameof(PeriodicRestartComputerHours));
+                }
+            }
+        }
+
+        public bool IsAutoRestartKernel {
+            get => NTMinerRoot.Instance.MinerProfile.IsAutoRestartKernel;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.IsAutoRestartKernel != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsAutoRestartKernel), value);
+                    OnPropertyChanged(nameof(IsAutoRestartKernel));
+                }
+            }
+        }
+
+        public int AutoRestartKernelTimes {
+            get => NTMinerRoot.Instance.MinerProfile.AutoRestartKernelTimes;
+            set {
+                if (value < 3) {
+                    value = 3;
+                }
+                if (NTMinerRoot.Instance.MinerProfile.AutoRestartKernelTimes != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(AutoRestartKernelTimes), value);
+                    OnPropertyChanged(nameof(AutoRestartKernelTimes));
+                }
+            }
+        }
+
+        public bool IsSpeedDownRestartComputer {
+            get => NTMinerRoot.Instance.MinerProfile.IsSpeedDownRestartComputer;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.IsSpeedDownRestartComputer != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsSpeedDownRestartComputer), value);
+                    OnPropertyChanged(nameof(IsSpeedDownRestartComputer));
+                }
+            }
+        }
+
+        public int PeriodicRestartKernelMinutes {
+            get => NTMinerRoot.Instance.MinerProfile.PeriodicRestartKernelMinutes;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.PeriodicRestartKernelMinutes != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(PeriodicRestartKernelMinutes), value);
+                    OnPropertyChanged(nameof(PeriodicRestartKernelMinutes));
+                    if (value < 0 || value > 60) {
+                        throw new ValidationException("无效的值");
+                    }
+                }
+            }
+        }
+
+        public int PeriodicRestartComputerMinutes {
+            get => NTMinerRoot.Instance.MinerProfile.PeriodicRestartComputerMinutes;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.PeriodicRestartComputerMinutes != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(PeriodicRestartComputerMinutes), value);
+                    OnPropertyChanged(nameof(PeriodicRestartComputerMinutes));
+                    if (value < 0 || value > 60) {
+                        throw new ValidationException("无效的值");
+                    }
+                }
+            }
+        }
+
+        public int RestartComputerSpeedDownPercent {
+            get => NTMinerRoot.Instance.MinerProfile.RestartComputerSpeedDownPercent;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.RestartComputerSpeedDownPercent != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(RestartComputerSpeedDownPercent), value);
+                    OnPropertyChanged(nameof(RestartComputerSpeedDownPercent));
+                }
+            }
+        }
+
+        public bool IsEChargeEnabled {
+            get => NTMinerRoot.Instance.MinerProfile.IsEChargeEnabled;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.IsEChargeEnabled != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsEChargeEnabled), value);
+                    OnPropertyChanged(nameof(IsEChargeEnabled));
+                }
+            }
+        }
+
+        public double EPrice {
+            get => NTMinerRoot.Instance.MinerProfile.EPrice;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.EPrice != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(EPrice), value);
+                    OnPropertyChanged(nameof(EPrice));
+                }
+            }
+        }
+
+        public bool IsPowerAppend {
+            get => NTMinerRoot.Instance.MinerProfile.IsPowerAppend;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.IsPowerAppend != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsPowerAppend), value);
+                    OnPropertyChanged(nameof(IsPowerAppend));
+                }
+            }
+        }
+
+        public int PowerAppend {
+            get => NTMinerRoot.Instance.MinerProfile.PowerAppend;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.PowerAppend != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(PowerAppend), value);
+                    OnPropertyChanged(nameof(PowerAppend));
+                }
+            }
+        }
+
+        public bool IsShowCommandLine {
+            get { return NTMinerRoot.GetIsShowCommandLine(); }
+            set {
+                if (NTMinerRoot.GetIsShowCommandLine() != value) {
+                    NTMinerRoot.SetIsShowCommandLine(value);
+                    OnPropertyChanged(nameof(IsShowCommandLine));
+                }
+            }
+        }
+
+        public Guid CoinId {
+            get => NTMinerRoot.Instance.MinerProfile.CoinId;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.CoinId != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(CoinId), value);
+                    OnPropertyChanged(nameof(CoinId));
+                }
+            }
+        }
+
+        public int MaxTemp {
+            get => NTMinerRoot.Instance.MinerProfile.MaxTemp;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.MaxTemp != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(MaxTemp), value);
+                    OnPropertyChanged(nameof(MaxTemp));
+                }
+            }
+        }
+
+        public int AutoStartDelaySeconds {
+            get => NTMinerRoot.Instance.MinerProfile.AutoStartDelaySeconds;
+            set {
+                if (NTMinerRoot.Instance.MinerProfile.AutoStartDelaySeconds != value) {
+                    NTMinerRoot.Instance.MinerProfile.SetMinerProfileProperty(nameof(AutoStartDelaySeconds), value);
+                    OnPropertyChanged(nameof(AutoStartDelaySeconds));
+                }
+            }
+        }
+
+        public CoinViewModel CoinVm {
+            get {
+                if (!AppContext.Instance.CoinVms.TryGetCoinVm(this.CoinId, out CoinViewModel coinVm) || !coinVm.IsSupported) {
+                    coinVm = AppContext.Instance.CoinVms.MainCoins.Where(a => a.IsSupported).FirstOrDefault();
+                    if (coinVm != null) {
+                        CoinId = coinVm.Id;
+                    }
+                }
+                return coinVm;
+            }
+            set {
+                if (value == null) {
+                    value = AppContext.Instance.CoinVms.MainCoins.Where(a => a.IsSupported).OrderBy(a => a.SortNumber).FirstOrDefault();
+                }
+                if (value != null) {
+                    this.CoinId = value.Id;
+                    OnPropertyChanged(nameof(CoinVm));
+                    NTMinerRoot.RefreshArgsAssembly.Invoke();
+                    AppContext.Instance.MinerProfileVm.OnPropertyChanged(nameof(AppContext.Instance.MinerProfileVm.IsAllMainCoinPoolIsUserMode));
+                }
+            }
+        }
+
+        public bool IsWorker {
+            get {
+                return MineWork != null && !VirtualRoot.IsMinerStudio;
+            }
+        }
+
+        public bool IsMining {
+            get => _isMining;
+            set {
+                _isMining = value;
+                OnPropertyChanged(nameof(IsMining));
+            }
+        }
+    }
+}

+ 1 - 1
src/AppModels/Vms/MinerStateViewModel.cs

@@ -20,7 +20,7 @@ namespace NTMiner.Vms {
             get; private set;
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }

+ 1 - 1
src/AppModels/Vms/SpeedChartViewModel.cs

@@ -96,7 +96,7 @@ namespace NTMiner.Vms {
             };
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }

+ 1 - 1
src/AppModels/Vms/SpeedChartsViewModel.cs

@@ -7,7 +7,7 @@
             _speedChartViewModels = new SpeedChartViewModels();
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }

+ 69 - 0
src/AppModels/Vms/StartStopMineButtonViewModel.cs

@@ -0,0 +1,69 @@
+using System.Windows.Input;
+
+namespace NTMiner.Vms {
+    public class StartStopMineButtonViewModel : ViewModelBase {
+        public static readonly StartStopMineButtonViewModel Instance = new StartStopMineButtonViewModel();
+
+        public ICommand StartMine { get; private set; }
+        public ICommand StopMine { get; private set; }
+
+        private StartStopMineButtonViewModel() {
+            if (Design.IsInDesignMode) {
+                return;
+            }
+#if DEBUG
+                VirtualRoot.Stopwatch.Restart();
+#endif
+            this.StartMine = new DelegateCommand(() => {
+                this.MinerProfile.IsMining = true;
+                NTMinerRoot.Instance.StartMine();
+                BtnStopText = "正在挖矿";
+            });
+            this.StopMine = new DelegateCommand(() => {
+                if (!NTMinerRoot.Instance.IsMining) {
+                    this.MinerProfile.IsMining = false;
+                }
+                NTMinerRoot.IsAutoStartCanceled = true;
+                NTMinerRoot.Instance.StopMineAsync(() => {
+                    if (!NTMinerRoot.Instance.IsMining) {
+                        this.MinerProfile.IsMining = false;
+                    }
+                });
+            });
+            if (NTMinerRoot.IsAutoStart && !this.MinerProfile.IsMining && VirtualRoot.SecondCount < MinerProfile.AutoStartDelaySeconds) {
+                this.MinerProfile.IsMining = true;
+                int n = MinerProfile.AutoStartDelaySeconds;
+                Bus.IDelegateHandler handler = null;
+                handler = AppContext.On<Per1SecondEvent>("挖矿倒计时", LogEnum.None,
+                action: message => {
+                    BtnStopText = $"倒计时({--n})";
+                    if (n <= 0) {
+                        BtnStopText = "正在挖矿";
+                        VirtualRoot.UnPath(handler);
+                        if (!NTMinerRoot.IsAutoStartCanceled) {
+                            NTMinerRoot.Instance.StartMine();
+                        }
+                    }
+                });
+            }
+#if DEBUG
+                Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {this.GetType().Name}.ctor");
+#endif
+        }
+
+        private string _btnStopText = "正在挖矿";
+        public string BtnStopText {
+            get => _btnStopText;
+            set {
+                _btnStopText = value;
+                OnPropertyChanged(nameof(BtnStopText));
+            }
+        }
+
+        public MinerProfileViewModel MinerProfile {
+            get {
+                return AppContext.Instance.MinerProfileVm;
+            }
+        }
+    }
+}

+ 2 - 2
src/AppModels/Vms/StateBarViewModel.cs

@@ -182,13 +182,13 @@ namespace NTMiner.Vms {
             }
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get {
                 return AppContext.Instance.MinerProfileVm;
             }
         }
 
-        public AppContext.GpuStatusBarViewModel GpuStatusBarVm {
+        public GpuStatusBarViewModel GpuStatusBarVm {
             get {
                 return AppContext.Instance.GpuStatusBarVm;
             }

+ 2 - 2
src/AppModels/Vms/ToolboxViewModel.cs

@@ -24,10 +24,10 @@ namespace NTMiner.Vms {
                 this.ShowDialog(message: $"确定运行吗?大概需要花费5到10秒钟时间看到结果", title: "确认", onYes: () => {
                     VirtualRoot.Execute(new SwitchRadeonGpuCommand());
                 }, icon: IconConst.IconConfirm);
-            }, () => NTMinerRoot.Instance.GpuSet.GpuType == GpuType.AMD && !AppContext.MinerProfileViewModel.Instance.IsMining);
+            }, () => NTMinerRoot.Instance.GpuSet.GpuType == GpuType.AMD && !MinerProfileViewModel.Instance.IsMining);
             this.AtikmdagPatcher = new DelegateCommand(() => {
                 VirtualRoot.Execute(new AtikmdagPatcherCommand());
-            }, () => NTMinerRoot.Instance.GpuSet.GpuType == GpuType.AMD && !AppContext.MinerProfileViewModel.Instance.IsMining);
+            }, () => NTMinerRoot.Instance.GpuSet.GpuType == GpuType.AMD && !MinerProfileViewModel.Instance.IsMining);
             this.NavigateToNvidiaDriverWin10 = new DelegateCommand(() => {
                 Process.Start("https://www.geforce.cn/drivers/results/137770");
             });

+ 1 - 1
src/AppModels/Vms/UserPageViewModel.cs

@@ -9,7 +9,7 @@
             }
         }
 
-        public AppContext.MinerProfileViewModel MinerProfile {
+        public MinerProfileViewModel MinerProfile {
             get { return AppContext.Instance.MinerProfileVm; }
         }
 

+ 143 - 0
src/AppModels/Vms/VirtualMemorySetViewModel.cs

@@ -0,0 +1,143 @@
+using Microsoft.Win32;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace NTMiner.Vms {
+    public class VirtualMemorySetViewModel : ViewModelBase, IEnumerable<VirtualMemoryViewModel> {
+        public static readonly VirtualMemorySetViewModel Instance = new VirtualMemorySetViewModel();
+
+        private readonly Dictionary<string, VirtualMemoryViewModel> _dic = new Dictionary<string, VirtualMemoryViewModel>(StringComparer.OrdinalIgnoreCase);
+
+        private readonly Dictionary<string, VirtualMemoryViewModel> _initialVms = new Dictionary<string, VirtualMemoryViewModel>(StringComparer.OrdinalIgnoreCase);
+        private VirtualMemorySetViewModel() {
+#if DEBUG
+                VirtualRoot.Stopwatch.Restart();
+#endif
+            foreach (var item in GetPagingFiles()) {
+                _initialVms.Add(item.DriveName, item);
+            }
+            foreach (var drive in AppContext.Instance.DriveSetVm.Drives) {
+                _dic.Add(drive.Name, new VirtualMemoryViewModel(drive.Name, 0));
+            }
+            foreach (var item in _initialVms.Values) {
+                if (_dic.TryGetValue(item.DriveName, out VirtualMemoryViewModel vm)) {
+                    vm.MaxSizeMb = item.MaxSizeMb;
+                }
+            }
+            NTMinerRoot.OSVirtualMemoryMb = _dic.Values.Sum(a => a.MaxSizeMb);
+#if DEBUG
+                Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {this.GetType().Name}.ctor");
+#endif
+        }
+
+        public bool IsStateChanged {
+            get {
+                foreach (var item in _dic.Values.Where(a => a.MaxSizeMb != 0)) {
+                    if (!_initialVms.ContainsKey(item.DriveName)) {
+                        return true;
+                    }
+                }
+                foreach (var item in _initialVms) {
+                    if (_dic[item.Key].MaxSizeB != item.Value.MaxSizeB) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+
+
+        public int TotalVirtualMemoryGb {
+            get {
+                return _dic.Values.Sum(a => a.MaxSizeGb);
+            }
+        }
+
+        public string TotalVirtualMemoryGbText {
+            get {
+                return TotalVirtualMemoryGb + " G";
+            }
+        }
+
+        private const string MemoryManagementSubKey = @"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management";
+        public void SetVirtualMemoryOfDrive() {
+            List<VirtualMemoryViewModel> virtualMemories = _dic.Values.Where(a => a.MaxSizeMb != 0).ToList();
+            string[] value = virtualMemories.Select(a => a.ToString()).ToArray();
+
+            Windows.WinRegistry.SetValue(Registry.LocalMachine, MemoryManagementSubKey, "PagingFiles", value);
+            OnPropertyChanged(nameof(TotalVirtualMemoryGb));
+            OnPropertyChanged(nameof(TotalVirtualMemoryGbText));
+            OnPropertyChanged(nameof(IsStateChanged));
+            NTMinerRoot.OSVirtualMemoryMb = _dic.Values.Sum(a => a.MaxSizeMb);
+        }
+
+        private List<VirtualMemoryViewModel> GetPagingFiles() {
+            object value = Windows.WinRegistry.GetValue(Registry.LocalMachine, MemoryManagementSubKey, "PagingFiles");
+            // REG_SZ or REG_MULTI_SZ
+            List<VirtualMemoryViewModel> list;
+            if (value is string[]) {
+                list = Parse((string[])value);
+            }
+            else {
+                list = new List<VirtualMemoryViewModel>();
+            }
+            return list;
+        }
+
+        private VirtualMemoryViewModel Parse(string vmReg) {
+            string driveName;
+            int minsize = 0;
+            int maxsize = 0;
+            try {
+                string[] strarr = vmReg.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
+                if (strarr.Length == 3) {
+                    driveName = strarr[0].Substring(0, 3);
+                    minsize = Convert.ToInt32(strarr[1]);
+                    maxsize = Convert.ToInt32(strarr[2]);
+                    return new VirtualMemoryViewModel(driveName, maxsize);
+                }
+                return null;
+            }
+            catch (Exception e) {
+                Logger.ErrorDebugLine(e);
+                return null;
+            }
+        }
+
+        private List<VirtualMemoryViewModel> Parse(string[] vmReg) {
+            List<VirtualMemoryViewModel> list = new List<VirtualMemoryViewModel>();
+            try {
+                foreach (string item in vmReg) {
+                    VirtualMemoryViewModel vm = Parse(item);
+                    if (vm != null) {
+                        list.Add(vm);
+                    }
+                }
+            }
+            catch (Exception e) {
+                Logger.ErrorDebugLine(e);
+            }
+            return list;
+        }
+
+        public VirtualMemoryViewModel this[string driveName] {
+            get {
+                return _dic[driveName];
+            }
+        }
+
+        public bool Contains(string driveName) {
+            return _dic.ContainsKey(driveName);
+        }
+
+        public IEnumerator<VirtualMemoryViewModel> GetEnumerator() {
+            return _dic.Values.GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator() {
+            return _dic.Values.GetEnumerator();
+        }
+    }
+}

+ 2 - 2
src/AppViews0/Ucs/GpuOverClock.xaml.cs

@@ -6,9 +6,9 @@ using System.Windows.Input;
 
 namespace NTMiner.Views.Ucs {
     public partial class GpuOverClock : UserControl {
-        public AppContext.MinerProfileViewModel Vm {
+        public MinerProfileViewModel Vm {
             get {
-                return (AppContext.MinerProfileViewModel)this.DataContext;
+                return (MinerProfileViewModel)this.DataContext;
             }
         }
 

+ 3 - 3
src/AppViews0/Ucs/MinerProfileDual.xaml.cs

@@ -5,14 +5,14 @@ using System.Windows.Controls.Primitives;
 
 namespace NTMiner.Views.Ucs {
     public partial class MinerProfileDual : UserControl {
-        private AppContext.MinerProfileViewModel Vm {
+        private MinerProfileViewModel Vm {
             get {
-                return AppContext.MinerProfileViewModel.Instance;
+                return MinerProfileViewModel.Instance;
             }
         }
 
         public MinerProfileDual() {
-            this.DataContext = AppContext.MinerProfileViewModel.Instance;
+            this.DataContext = MinerProfileViewModel.Instance;
             InitializeComponent();
             this.PopupDualCoinPool.Closed += Popup_Closed;
             this.PopupDualCoin.Closed += Popup_Closed;

+ 3 - 3
src/AppViews0/Ucs/MinerProfileOption.xaml.cs

@@ -1,11 +1,11 @@
-using System.Windows;
+using NTMiner.Vms;
 using System.Windows.Controls;
 
 namespace NTMiner.Views.Ucs {
     public partial class MinerProfileOption : UserControl {
-        public AppContext.MinerProfileViewModel Vm {
+        public MinerProfileViewModel Vm {
             get {
-                return (AppContext.MinerProfileViewModel)this.DataContext;
+                return (MinerProfileViewModel)this.DataContext;
             }
         }
 

+ 3 - 2
src/AppViews0/Ucs/StartStopMineButton.xaml.cs

@@ -1,4 +1,5 @@
-using System.ComponentModel;
+using NTMiner.Vms;
+using System.ComponentModel;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media;
@@ -22,7 +23,7 @@ namespace NTMiner.Views.Ucs {
         public static readonly DependencyProperty StartButtonForegroundProperty =
             DependencyProperty.Register("StartButtonForeground", typeof(SolidColorBrush), typeof(StartStopMineButton), new PropertyMetadata(Wpf.Util.TransparentBrush));
 
-        private AppContext.StartStopMineButtonViewModel Vm {
+        private StartStopMineButtonViewModel Vm {
             get {
                 return AppContext.Instance.StartStopMineButtonVm;
             }