diff --git a/VS2022/Command1.cs b/VS2022/Command1.cs index 30c5a8b..0f6b844 100644 --- a/VS2022/Command1.cs +++ b/VS2022/Command1.cs @@ -8,6 +8,8 @@ using Task = System.Threading.Tasks.Task; using EnvDTE; using System.IO; +using Microsoft.VisualStudio.Settings; +using Microsoft.VisualStudio.Shell.Settings; namespace ResourceMonitor { @@ -20,38 +22,9 @@ internal sealed class Command1: AsyncPackage private static Disk disk; /*Options*/ - private static int refreshInterval = 1; - private bool showCPU; - private bool showRam; - private static SizeUnit ramUsageUnit; - private static SizeUnit ramTotalUnit; - private bool showVSRam; - - private bool showDisk; - - private bool showBatteryPercent; - private bool showBatteryTime; - - private void UpdateSettings() - { - var options = (OptionPage)GetDialogPage(typeof(OptionPage)); - - refreshInterval = options.RefreshInterval; - - showCPU = options.ShowCPU; - - showRam = options.ShowRAM; - ramUsageUnit = options.RamUsageUnit; - ramTotalUnit = options.TotalRamUnit; - showVSRam = options.ShowVSRAM; - - showDisk = options.ShowDisk; - - showBatteryPercent = options.ShowBatteryPercent; - showBatteryTime = options.ShowBatteryTime; - } + static public ShellSettingsManager ShellSettingsManager; /// /// Command ID. @@ -117,9 +90,13 @@ public static async Task InitializeAsync(AsyncPackage package) OleMenuCommandService commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService; Instance = new Command1(package, commandService); + + var service = (await Instance.ServiceProvider.GetServiceAsync(typeof(SVsSettingsManager))) as IVsSettingsManager; + ShellSettingsManager = new ShellSettingsManager(service); } + private static string SizeUnitToStr(SizeUnit unit) { switch (unit) @@ -137,9 +114,14 @@ private static string SizeUnitToStr(SizeUnit unit) private async Task GetSolutionDir() { + await JoinableTaskFactory.SwitchToMainThreadAsync(DisposalToken); try { - var env = await ServiceProvider.GetServiceAsync(typeof(SDTE)) as DTE; + //var env = await ServiceProvider.GetServiceAsync(typeof(SDTE)) as DTE; //This crash in VS2022 + var env = (EnvDTE80.DTE2)await ServiceProvider.GetServiceAsync(typeof(SDTE)); + if (env.Solution == null || env.Solution.FullName.Length == 0) + return; + var solutionDir = new FileInfo(env.Solution.FullName); disk = solutionDir.Extension.Length == 0 ? new Disk(env.Solution.FullName) : @@ -155,50 +137,50 @@ private async Task DoUpdate() var statusBar = await ServiceProvider.GetServiceAsync(typeof(SVsStatusbar)) as IVsStatusbar; while (true) { - UpdateSettings(); + var options = OptionPage.Fields; string str=string.Empty; - if (showCPU) + if (options.showCPU) str += $"CPU: {CPU.Usage} %"; - if (showRam || showVSRam) + if (options.showRam || options.showVSRam) { str += $" RAM: "; - if (showVSRam) + if (options.showVSRam) { - if(ramUsageUnit != SizeUnit.GB) - str += $"{RAM.VsUsage(ramUsageUnit):0.}"; + if(options.ramUsageUnit != SizeUnit.GB) + str += $"{RAM.VsUsage(options.ramUsageUnit):0.}"; else str += $"{RAM.VsUsage(SizeUnit.GB):0.#}"; - str += SizeUnitToStr(ramUsageUnit); + str += SizeUnitToStr(options.ramUsageUnit); } - if (showVSRam && showRam) + if (options.showVSRam && options.showRam) str += " / "; - if (showRam) + if (options.showRam) { - if(ramTotalUnit!=SizeUnit.GB) - str += $"{RAM.TotalUsage(ramTotalUnit):0.}"; + if(options.ramTotalUnit !=SizeUnit.GB) + str += $"{RAM.TotalUsage(options.ramTotalUnit):0.}"; else str += $"{RAM.TotalUsage(SizeUnit.GB):0.#}"; - str += SizeUnitToStr(ramTotalUnit); + str += SizeUnitToStr(options.ramTotalUnit); } } - if (showDisk) + if (options.showDisk) { if(disk!=null) str += $" Disk: {disk.SolutionSize(SizeUnit.MB):0.#}MB"; else - GetSolutionDir(); + await GetSolutionDir(); } - if (showBatteryPercent || showBatteryTime) + if (options.showBatteryPercent || options.showBatteryTime) { str += " Battery:"; - if (showBatteryPercent) + if (options.showBatteryPercent) str += $" {Battery.BatteryPercent * 100} %"; - if (showBatteryTime) + if (options.showBatteryTime) { var batteryRemain = Battery.BatteryRemains; str += $" {batteryRemain.Item1} h {batteryRemain.Item2} min"; @@ -213,7 +195,7 @@ private async Task DoUpdate() statusBar?.SetText(existingText + " | " + str); statusBar.FreezeOutput(1); - System.Threading.Thread.Sleep(refreshInterval * 1000); + await Task.Delay(options.refreshInterval * 1000); } } diff --git a/VS2022/Options.cs b/VS2022/Options.cs index d71fe9e..8ed0855 100644 --- a/VS2022/Options.cs +++ b/VS2022/Options.cs @@ -1,68 +1,197 @@ using Microsoft.VisualStudio; using Microsoft.VisualStudio.OLE.Interop; -using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Settings; using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Settings; using Microsoft.Win32; using System; using System.ComponentModel; using System.ComponentModel.Design; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Task = System.Threading.Tasks.Task; +using Microsoft.VisualStudio.Shell; +using Newtonsoft.Json; +using System.IO; +using System.Linq; namespace ResourceMonitor { + [Serializable] + public class Fields + { + public int refreshInterval { get; set; } = 1; + public bool showCPU { get; set; } = true; + public bool showRam { get; set; } = true; + public SizeUnit ramUsageUnit { get; set; } = SizeUnit.MB; + public SizeUnit ramTotalUnit { get; set; } = SizeUnit.GB; + public bool showVSRam { get; set; } = true; + public bool showDisk { get; set; } = true; + public bool showBatteryPercent { get; set; } = true; + public bool showBatteryTime { get; set; } = true; + } public class OptionPage:DialogPage { [Category("Refresh")] [DisplayName("Refresh interval (seconds)")] [Description("Refresh interval (seconds)")] - public int RefreshInterval { get; set; } = 1; + public int RefreshInterval + { + get => Fields.refreshInterval; + set + { + Fields.refreshInterval = value; + save(); + } + } [Category("CPU")] [DisplayName("Show CPU Usage")] [Description("Show CPU Usage")] - public bool ShowCPU { get; set; } = true; + public bool ShowCPU + { + get => Fields.showCPU; + set + { + Fields.showCPU = value; + save(); + } + } [Category("RAM")] [DisplayName("Show Total system RAM Usage")] [Description("Show Total system RAM Usage")] - public bool ShowRAM { get; set; } = true; + public bool ShowRAM + { + get => Fields.showRam; + set + { + Fields.showRam = value; + save() ; + } + } [Category("RAM")] [DisplayName("Show RAM Usage of Visual Studio")] [Description("Show RAM Usage of Visual Studio")] - public bool ShowVSRAM { get; set; } = true; + public bool ShowVSRAM + { + get => Fields.showVSRam; + set + { + Fields.showVSRam = value; + save(); + } + } [Category("RAM")] [DisplayName("Unit for Visual Studio RAM usage")] [Description("Unit for Visual Studio RAM usage")] - public SizeUnit RamUsageUnit { get; set; } = SizeUnit.MB; + public SizeUnit RamUsageUnit + { + get => Fields.ramUsageUnit; + set + { + Fields.ramUsageUnit = value; + save(); + } + } [Category("RAM")] [DisplayName("Unit for total system RAM usage")] [Description("Unit for total system RAM usage")] - public SizeUnit TotalRamUnit { get; set; } = SizeUnit.GB; + public SizeUnit TotalRamUnit + { + get => Fields.ramTotalUnit; + set + { + Fields.ramTotalUnit = value; + save(); + } + } [Category("Disk")] [DisplayName("Show Solution Disk Usage")] [Description("Show Solution Disk Usage")] - public bool ShowDisk { get; set; } = true; + public bool ShowDisk + { + get => Fields.showDisk; + set + { + Fields.showDisk = value; + save(); + } + } [Category("Battery")] [DisplayName("Show Battery Percentage")] [Description("Show Battery Percentage")] - public bool ShowBatteryPercent { get; set; } = true; + public bool ShowBatteryPercent + { + get => Fields.showBatteryPercent; + set + { + Fields.showBatteryPercent = value; + save(); + } + } [Category("Battery")] [DisplayName("Show Battery Remaining Time")] [Description("Show Battery Remaining Time")] - public bool ShowBatteryTime { get; set; } = true; + public bool ShowBatteryTime + { + get => Fields.showBatteryTime; + set + { + Fields.showBatteryTime = value; + save(); + } + } + + const string CollectionName = "ResourceMonitor.OptionPage"; + + static public Fields Fields; + + static OptionPage() + { + var store = Command1.ShellSettingsManager.GetWritableSettingsStore(SettingsScope.UserSettings); + try + { + if (store.CollectionExists(CollectionName)) + { + using (var reader = new JsonTextReader(new StringReader(store.GetString(CollectionName, "Value")))) + { + Fields = new JsonSerializer().Deserialize(reader); + return; + } + } + } + catch (Exception) + { + } + Fields = new Fields(); + } + + async void save() + { + var store = Command1.ShellSettingsManager.GetWritableSettingsStore(SettingsScope.UserSettings); + store.CreateCollection("ResourceMonitor.OptionPage"); + using (var sw = new StringWriter()) + { + using (var writer = new JsonTextWriter(sw)) + { + new JsonSerializer().Serialize(writer, Fields); + store.SetString("ResourceMonitor.OptionPage", "Value", sw.ToString()); + } + } + } } [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)] diff --git a/VS2022/ResourceMonitorPackage.cs b/VS2022/ResourceMonitorPackage.cs index f2fca88..1ce7765 100644 --- a/VS2022/ResourceMonitorPackage.cs +++ b/VS2022/ResourceMonitorPackage.cs @@ -30,6 +30,14 @@ namespace ResourceMonitor [ProvideAutoLoad(UIContextGuids80.SolutionExists, PackageAutoLoadFlags.BackgroundLoad)] [ProvideAutoLoad(UIContextGuids80.NoSolution, PackageAutoLoadFlags.BackgroundLoad)] [ProvideAutoLoad(UIContextGuids80.EmptySolution, PackageAutoLoadFlags.BackgroundLoad)] + [ProvideOptionPage( + typeof(OptionPage), + "Resource Monitor", + "General", + 0, + 0, + true) + ] public sealed class ResourceMonitorPackage : AsyncPackage { ///