|
18 | 18 | using Microsoft.VisualStudio.Workspace;
|
19 | 19 | using Microsoft.VisualStudio.Workspace.Indexing;
|
20 | 20 | using Microsoft.VisualStudio.Workspace.VSIntegration.Contracts;
|
| 21 | +using Microsoft.Win32; |
21 | 22 |
|
22 | 23 | namespace Microsoft.DebugEngineHost
|
23 | 24 | {
|
| 25 | + internal class RegisterMonitorWrapper : IDisposable |
| 26 | + { |
| 27 | + public RegistryMonitor CurrentMonitor { get; set; } |
| 28 | + |
| 29 | + internal RegisterMonitorWrapper(RegistryMonitor currentMonitor) |
| 30 | + { |
| 31 | + CurrentMonitor = currentMonitor; |
| 32 | + } |
| 33 | + |
| 34 | + public void Dispose() |
| 35 | + { |
| 36 | + CurrentMonitor.Dispose(); |
| 37 | + CurrentMonitor = null; |
| 38 | + } |
| 39 | + } |
| 40 | + |
24 | 41 | /// <summary>
|
25 | 42 | /// Provides interactions with the host's source workspace to locate and load any natvis files
|
26 | 43 | /// in the project.
|
@@ -49,6 +66,113 @@ public static void FindNatvis(NatvisLoader loader)
|
49 | 66 | paths.ForEach((s) => loader(s));
|
50 | 67 | }
|
51 | 68 |
|
| 69 | + public static IDisposable WatchNatvisOptionSetting(HostConfigurationStore configStore, ILogChannel natvisLogger) |
| 70 | + { |
| 71 | + RegisterMonitorWrapper rmw = null; |
| 72 | + |
| 73 | + HostConfigurationSection natvisDiagnosticSection = configStore.GetNatvisDiagnosticSection(); |
| 74 | + if (natvisDiagnosticSection != null) |
| 75 | + { |
| 76 | + // DiagnosticSection exists, set current log level and watch for changes. |
| 77 | + SetNatvisLogLevel(natvisDiagnosticSection); |
| 78 | + |
| 79 | + rmw = new RegisterMonitorWrapper(CreateAndStartNatvisDiagnosticMonitor(natvisDiagnosticSection, natvisLogger)); |
| 80 | + } |
| 81 | + else |
| 82 | + { |
| 83 | + // NatvisDiagnostic section has not been created, we need to watch for the creation. |
| 84 | + HostConfigurationSection debuggerSection = configStore.GetCurrentUserDebuggerSection(); |
| 85 | + |
| 86 | + if (debuggerSection != null) |
| 87 | + { |
| 88 | + // We only care about the debugger subkey's keys since we are waiting for the NatvisDiagnostics |
| 89 | + // section to be created. |
| 90 | + RegistryMonitor rm = new RegistryMonitor(debuggerSection, false, natvisLogger); |
| 91 | + |
| 92 | + rmw = new RegisterMonitorWrapper(rm); |
| 93 | + |
| 94 | + rm.RegChanged += (sender, e) => |
| 95 | + { |
| 96 | + HostConfigurationSection checkForSection = configStore.GetNatvisDiagnosticSection(); |
| 97 | + |
| 98 | + if (checkForSection != null) |
| 99 | + { |
| 100 | + // NatvisDiagnostic section found. Update the logger |
| 101 | + SetNatvisLogLevel(checkForSection); |
| 102 | + |
| 103 | + // Remove debugger section tracking |
| 104 | + IDisposable disposable = rmw.CurrentMonitor; |
| 105 | + |
| 106 | + // Watch NatvisDiagnostic section |
| 107 | + rmw = new RegisterMonitorWrapper(CreateAndStartNatvisDiagnosticMonitor(natvisDiagnosticSection, natvisLogger)); |
| 108 | + |
| 109 | + disposable.Dispose(); |
| 110 | + } |
| 111 | + }; |
| 112 | + |
| 113 | + rm.Start(); |
| 114 | + } |
| 115 | + } |
| 116 | + |
| 117 | + |
| 118 | + return rmw; |
| 119 | + } |
| 120 | + |
| 121 | + private static RegistryMonitor CreateAndStartNatvisDiagnosticMonitor(HostConfigurationSection natvisDiagnosticSection, ILogChannel natvisLogger) |
| 122 | + { |
| 123 | + RegistryMonitor rm = new RegistryMonitor(natvisDiagnosticSection, true, natvisLogger); |
| 124 | + |
| 125 | + rm.RegChanged += (sender, e) => |
| 126 | + { |
| 127 | + SetNatvisLogLevel(natvisDiagnosticSection); |
| 128 | + }; |
| 129 | + |
| 130 | + rm.Start(); |
| 131 | + |
| 132 | + return rm; |
| 133 | + } |
| 134 | + |
| 135 | + private static void SetNatvisLogLevel(HostConfigurationSection natvisDiagnosticSection) |
| 136 | + { |
| 137 | + string level = natvisDiagnosticSection.GetValue("Level") as string; |
| 138 | + if (level != null) |
| 139 | + { |
| 140 | + level = level.ToLower(CultureInfo.InvariantCulture); |
| 141 | + } |
| 142 | + LogLevel logLevel; |
| 143 | + switch (level) |
| 144 | + { |
| 145 | + case "off": |
| 146 | + logLevel = LogLevel.None; |
| 147 | + break; |
| 148 | + case "error": |
| 149 | + logLevel = LogLevel.Error; |
| 150 | + break; |
| 151 | + case "warning": |
| 152 | + logLevel = LogLevel.Warning; |
| 153 | + break; |
| 154 | + case "verbose": |
| 155 | + logLevel = LogLevel.Verbose; |
| 156 | + break; |
| 157 | + default: // Unknown, default to Warning |
| 158 | + logLevel = LogLevel.Warning; |
| 159 | + break; |
| 160 | + } |
| 161 | + |
| 162 | + if (logLevel == LogLevel.None) |
| 163 | + { |
| 164 | + HostLogger.DisableNatvisDiagnostics(); |
| 165 | + } |
| 166 | + else |
| 167 | + { |
| 168 | + HostLogger.EnableNatvisDiagnostics((message) => { |
| 169 | + string formattedMessage = string.Format(CultureInfo.InvariantCulture, "Natvis: {0}", message); |
| 170 | + HostOutputWindow.WriteLaunchError(formattedMessage); |
| 171 | + }, logLevel); |
| 172 | + HostLogger.GetNatvisLogChannel().SetLogLevel(logLevel); |
| 173 | + } |
| 174 | + } |
| 175 | + |
52 | 176 | public static string FindSolutionRoot()
|
53 | 177 | {
|
54 | 178 | string path = null;
|
|
0 commit comments