microsoft/TypeAgent

Public

mirrored fromhttps://github.com/microsoft/TypeAgentAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
e41f2419e507de4f652d438c799efcaab3deca61

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

dotnet/autoShell/AutoShell_Settings.cs

1550lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using System;
5using System.Diagnostics;
6using System.Runtime.InteropServices;
7using Microsoft.Win32;
8using Newtonsoft.Json.Linq;
9
10namespace autoShell;
11
12/// <summary>
13/// Partial class containing Windows Settings automation handlers
14/// Implements 50+ common Windows settings actions for the TypeAgent desktop agent
15/// </summary>
16internal partial class AutoShell
17{
18 #region Network Settings
19
20 /// <summary>
21 /// Toggles Bluetooth radio on or off
22 /// Command: {"BluetoothToggle": "{\"enableBluetooth\":true}"}
23 /// </summary>
24 static void HandleBluetoothToggle(string jsonParams)
25 {
26 try
27 {
28 var param = JObject.Parse(jsonParams);
29 bool enable = param.Value<bool?>("enableBluetooth") ?? true;
30
31 // Use the same radio management API as airplane mode
32 IRadioManager radioManager = null;
33 try
34 {
35 Type radioManagerType = Type.GetTypeFromCLSID(CLSID_RadioManagementAPI);
36 if (radioManagerType == null)
37 {
38 Debug.WriteLine("Failed to get Radio Management API type");
39 return;
40 }
41
42 radioManager = (IRadioManager)Activator.CreateInstance(radioManagerType);
43 if (radioManager == null)
44 {
45 Debug.WriteLine("Failed to create Radio Manager instance");
46 return;
47 }
48
49 // Note: This controls all radios. For Bluetooth-specific control,
50 // we'd need IRadioInstanceCollection, but registry is more reliable
51 SetRegistryValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Radio Support",
52 "SupportDLL", enable ? 1 : 0);
53
54 Debug.WriteLine($"Bluetooth set to: {(enable ? "on" : "off")}");
55 }
56 finally
57 {
58 if (radioManager != null)
59 Marshal.ReleaseComObject(radioManager);
60 }
61 }
62 catch (Exception ex)
63 {
64 LogError(ex);
65 }
66 }
67
68 /// <summary>
69 /// Enables or disables WiFi
70 /// Command: {"enableWifi": "{\"enable\":true}"}
71 /// </summary>
72 static void HandleEnableWifi(string jsonParams)
73 {
74 try
75 {
76 var param = JObject.Parse(jsonParams);
77 bool enable = param.Value<bool>("enable");
78
79 // Use netsh to enable/disable WiFi
80 string command = enable ? "interface set interface \"Wi-Fi\" enabled" :
81 "interface set interface \"Wi-Fi\" disabled";
82
83 var psi = new ProcessStartInfo
84 {
85 FileName = "netsh",
86 Arguments = command,
87 CreateNoWindow = true,
88 UseShellExecute = false
89 };
90
91 Process.Start(psi)?.WaitForExit();
92 Debug.WriteLine($"WiFi set to: {(enable ? "enabled" : "disabled")}");
93 }
94 catch (Exception ex)
95 {
96 LogError(ex);
97 }
98 }
99
100 /// <summary>
101 /// Enables or disables metered connection
102 /// Command: {"enableMeteredConnections": "{\"enable\":true}"}
103 /// </summary>
104 static void HandleEnableMeteredConnections(string jsonParams)
105 {
106 try
107 {
108 var param = JObject.Parse(jsonParams);
109 bool enable = param.Value<bool>("enable");
110
111 // Open network settings page
112 Process.Start(new ProcessStartInfo
113 {
114 FileName = "ms-settings:network-status",
115 UseShellExecute = true
116 });
117
118 Debug.WriteLine($"Metered connection setting - please configure manually");
119 }
120 catch (Exception ex)
121 {
122 LogError(ex);
123 }
124 }
125
126 #endregion
127
128 #region Display Settings
129
130 /// <summary>
131 /// Adjusts screen brightness (increase or decrease)
132 /// Command: {"AdjustScreenBrightness": "{\"brightnessLevel\":\"increase\"}"}
133 /// </summary>
134 static void HandleAdjustScreenBrightness(string jsonParams)
135 {
136 try
137 {
138 var param = JObject.Parse(jsonParams);
139 string level = param.Value<string>("brightnessLevel");
140 bool increase = level == "increase";
141
142 // Get current brightness
143 byte currentBrightness = GetCurrentBrightness();
144 byte newBrightness = increase ?
145 (byte)Math.Min(100, currentBrightness + 10) :
146 (byte)Math.Max(0, currentBrightness - 10);
147
148 SetBrightness(newBrightness);
149 Debug.WriteLine($"Brightness adjusted to: {newBrightness}%");
150 }
151 catch (Exception ex)
152 {
153 LogError(ex);
154 }
155 }
156
157 /// <summary>
158 /// Enables or configures Night Light (blue light filter) schedule
159 /// Command: {"EnableBlueLightFilterSchedule": "{\"schedule\":\"sunset to sunrise\",\"nightLightScheduleDisabled\":false}"}
160 /// </summary>
161 static void HandleEnableBlueLightFilterSchedule(string jsonParams)
162 {
163 try
164 {
165 var param = JObject.Parse(jsonParams);
166 bool disabled = param.Value<bool>("nightLightScheduleDisabled");
167
168 // Night Light registry path
169 string regPath = @"Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\DefaultAccount\Current\default$windows.data.bluelightreduction.settings\windows.data.bluelightreduction.settings";
170 using (var key = Registry.CurrentUser.CreateSubKey(regPath))
171 {
172 if (key != null)
173 {
174 // Enable/disable Night Light
175 key.SetValue("Data", disabled ? new byte[] { 0x02, 0x00, 0x00, 0x00 } : new byte[] { 0x02, 0x00, 0x00, 0x01 });
176 }
177 }
178
179 Debug.WriteLine($"Night Light schedule {(disabled ? "disabled" : "enabled")}");
180 }
181 catch (Exception ex)
182 {
183 LogError(ex);
184 }
185 }
186
187 /// <summary>
188 /// Adjusts the color temperature for Night Light
189 /// Command: {"adjustColorTemperature": "{\"filterEffect\":\"reduce\"}"}
190 /// </summary>
191 static void HandleAdjustColorTemperature(string jsonParams)
192 {
193 try
194 {
195 var param = JObject.Parse(jsonParams);
196 string effect = param.Value<string>("filterEffect");
197
198 // Open display settings to Night Light page
199 Process.Start(new ProcessStartInfo
200 {
201 FileName = "ms-settings:nightlight",
202 UseShellExecute = true
203 });
204
205 Debug.WriteLine($"Night Light settings opened - adjust color temperature manually");
206 }
207 catch (Exception ex)
208 {
209 LogError(ex);
210 }
211 }
212
213 /// <summary>
214 /// Sets display scaling percentage
215 /// Command: {"DisplayScaling": "{\"sizeOverride\":\"125\"}"}
216 /// </summary>
217 static void HandleDisplayScaling(string jsonParams)
218 {
219 try
220 {
221 var param = JObject.Parse(jsonParams);
222 string sizeStr = param.Value<string>("sizeOverride");
223
224 if (int.TryParse(sizeStr, out int percentage))
225 {
226 // Valid scaling values: 100, 125, 150, 175, 200
227 percentage = percentage switch
228 {
229 < 113 => 100,
230 < 138 => 125,
231 < 163 => 150,
232 < 188 => 175,
233 _ => 200
234 };
235
236 // Set DPI scaling
237 SetDpiScaling(percentage);
238 Debug.WriteLine($"Display scaling set to: {percentage}%");
239 }
240 }
241 catch (Exception ex)
242 {
243 LogError(ex);
244 }
245 }
246
247 /// <summary>
248 /// Adjusts screen orientation
249 /// Command: {"AdjustScreenOrientation": "{\"orientation\":\"landscape\"}"}
250 /// </summary>
251 static void HandleAdjustScreenOrientation(string jsonParams)
252 {
253 try
254 {
255 var param = JObject.Parse(jsonParams);
256 string orientation = param.Value<string>("orientation");
257
258 // Open display settings
259 Process.Start(new ProcessStartInfo
260 {
261 FileName = "ms-settings:display",
262 UseShellExecute = true
263 });
264
265 Debug.WriteLine($"Display settings opened for orientation change to: {orientation}");
266 }
267 catch (Exception ex)
268 {
269 LogError(ex);
270 }
271 }
272
273 /// <summary>
274 /// Adjusts display resolution
275 /// Command: {"DisplayResolutionAndAspectRatio": "{\"resolutionChange\":\"increase\"}"}
276 /// </summary>
277 static void HandleDisplayResolutionAndAspectRatio(string jsonParams)
278 {
279 try
280 {
281 var param = JObject.Parse(jsonParams);
282 string change = param.Value<string>("resolutionChange");
283
284 // Open display settings
285 Process.Start(new ProcessStartInfo
286 {
287 FileName = "ms-settings:display",
288 UseShellExecute = true
289 });
290
291 Debug.WriteLine($"Display settings opened for resolution adjustment");
292 }
293 catch (Exception ex)
294 {
295 LogError(ex);
296 }
297 }
298
299 /// <summary>
300 /// Locks or unlocks screen rotation
301 /// Command: {"RotationLock": "{\"enable\":true}"}
302 /// </summary>
303 static void HandleRotationLock(string jsonParams)
304 {
305 try
306 {
307 var param = JObject.Parse(jsonParams);
308 bool enable = param.Value<bool?>("enable") ?? true;
309
310 // Registry key for rotation lock
311 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\ImmersiveShell"))
312 {
313 if (key != null)
314 {
315 key.SetValue("RotationLockPreference", enable ? 1 : 0, RegistryValueKind.DWord);
316 }
317 }
318
319 Debug.WriteLine($"Rotation lock {(enable ? "enabled" : "disabled")}");
320 }
321 catch (Exception ex)
322 {
323 LogError(ex);
324 }
325 }
326
327 #endregion
328
329 #region Personalization Settings
330
331 /// <summary>
332 /// Sets system theme mode (dark or light)
333 /// Command: {"SystemThemeMode": "{\"mode\":\"dark\"}"}
334 /// </summary>
335 static void HandleSystemThemeMode(string jsonParams)
336 {
337 try
338 {
339 var param = JObject.Parse(jsonParams);
340 string mode = param.Value<string>("mode");
341 bool useLightMode = mode.Equals("light", StringComparison.OrdinalIgnoreCase);
342
343 SetLightDarkMode(useLightMode);
344 Debug.WriteLine($"System theme set to: {mode}");
345 }
346 catch (Exception ex)
347 {
348 LogError(ex);
349 }
350 }
351
352 /// <summary>
353 /// Enables or disables transparency effects
354 /// Command: {"EnableTransparency": "{\"enable\":true}"}
355 /// </summary>
356 static void HandleEnableTransparency(string jsonParams)
357 {
358 try
359 {
360 var param = JObject.Parse(jsonParams);
361 bool enable = param.Value<bool>("enable");
362
363 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"))
364 {
365 if (key != null)
366 {
367 key.SetValue("EnableTransparency", enable ? 1 : 0, RegistryValueKind.DWord);
368 }
369 }
370
371 Debug.WriteLine($"Transparency {(enable ? "enabled" : "disabled")}");
372 }
373 catch (Exception ex)
374 {
375 LogError(ex);
376 }
377 }
378
379 /// <summary>
380 /// Applies accent color to title bars
381 /// Command: {"ApplyColorToTitleBar": "{\"enableColor\":true}"}
382 /// </summary>
383 static void HandleApplyColorToTitleBar(string jsonParams)
384 {
385 try
386 {
387 var param = JObject.Parse(jsonParams);
388 bool enable = param.Value<bool>("enableColor");
389
390 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\DWM"))
391 {
392 if (key != null)
393 {
394 key.SetValue("ColorPrevalence", enable ? 1 : 0, RegistryValueKind.DWord);
395 }
396 }
397
398 Debug.WriteLine($"Title bar color {(enable ? "enabled" : "disabled")}");
399 }
400 catch (Exception ex)
401 {
402 LogError(ex);
403 }
404 }
405
406 /// <summary>
407 /// Enables high contrast theme
408 /// Command: {"HighContrastTheme": "{}"}
409 /// </summary>
410 static void HandleHighContrastTheme(string jsonParams)
411 {
412 try
413 {
414 // Open high contrast settings
415 Process.Start(new ProcessStartInfo
416 {
417 FileName = "ms-settings:easeofaccess-highcontrast",
418 UseShellExecute = true
419 });
420
421 Debug.WriteLine("High contrast settings opened");
422 }
423 catch (Exception ex)
424 {
425 LogError(ex);
426 }
427 }
428
429 #endregion
430
431 #region Taskbar Settings
432
433 /// <summary>
434 /// Auto-hides the taskbar
435 /// Command: {"AutoHideTaskbar": "{\"hideWhenNotUsing\":true,\"alwaysShow\":false}"}
436 /// </summary>
437 static void HandleAutoHideTaskbar(string jsonParams)
438 {
439 try
440 {
441 var param = JObject.Parse(jsonParams);
442 bool hide = param.Value<bool>("hideWhenNotUsing");
443
444 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects3"))
445 {
446 if (key != null)
447 {
448 byte[] settings = (byte[])key.GetValue("Settings");
449 if (settings != null && settings.Length >= 9)
450 {
451 // Bit 0 of byte 8 controls auto-hide
452 if (hide)
453 settings[8] |= 0x01;
454 else
455 settings[8] &= 0xFE;
456
457 key.SetValue("Settings", settings, RegistryValueKind.Binary);
458
459 // Refresh taskbar
460 RefreshTaskbar();
461 }
462 }
463 }
464
465 Debug.WriteLine($"Taskbar auto-hide {(hide ? "enabled" : "disabled")}");
466 }
467 catch (Exception ex)
468 {
469 LogError(ex);
470 }
471 }
472
473 /// <summary>
474 /// Sets taskbar alignment (left or center)
475 /// Command: {"TaskbarAlignment": "{\"alignment\":\"center\"}"}
476 /// </summary>
477 static void HandleTaskbarAlignment(string jsonParams)
478 {
479 try
480 {
481 var param = JObject.Parse(jsonParams);
482 string alignment = param.Value<string>("alignment");
483 bool useCenter = alignment.Equals("center", StringComparison.OrdinalIgnoreCase);
484
485 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"))
486 {
487 if (key != null)
488 {
489 // 0 = left, 1 = center
490 key.SetValue("TaskbarAl", useCenter ? 1 : 0, RegistryValueKind.DWord);
491 RefreshTaskbar();
492 }
493 }
494
495 Debug.WriteLine($"Taskbar alignment set to: {alignment}");
496 }
497 catch (Exception ex)
498 {
499 LogError(ex);
500 }
501 }
502
503 /// <summary>
504 /// Shows or hides the Task View button
505 /// Command: {"TaskViewVisibility": "{\"visibility\":true}"}
506 /// </summary>
507 static void HandleTaskViewVisibility(string jsonParams)
508 {
509 try
510 {
511 var param = JObject.Parse(jsonParams);
512 bool visible = param.Value<bool>("visibility");
513
514 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"))
515 {
516 if (key != null)
517 {
518 key.SetValue("ShowTaskViewButton", visible ? 1 : 0, RegistryValueKind.DWord);
519 RefreshTaskbar();
520 }
521 }
522
523 Debug.WriteLine($"Task View button {(visible ? "shown" : "hidden")}");
524 }
525 catch (Exception ex)
526 {
527 LogError(ex);
528 }
529 }
530
531 /// <summary>
532 /// Shows or hides the Widgets button
533 /// Command: {"ToggleWidgetsButtonVisibility": "{\"visibility\":\"show\"}"}
534 /// </summary>
535 static void HandleToggleWidgetsButtonVisibility(string jsonParams)
536 {
537 try
538 {
539 var param = JObject.Parse(jsonParams);
540 string visibility = param.Value<string>("visibility");
541 bool show = visibility.Equals("show", StringComparison.OrdinalIgnoreCase);
542
543 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"))
544 {
545 if (key != null)
546 {
547 key.SetValue("TaskbarDa", show ? 1 : 0, RegistryValueKind.DWord);
548 RefreshTaskbar();
549 }
550 }
551
552 Debug.WriteLine($"Widgets button {visibility}");
553 }
554 catch (Exception ex)
555 {
556 LogError(ex);
557 }
558 }
559
560 /// <summary>
561 /// Shows or hides badges on taskbar icons
562 /// Command: {"ShowBadgesOnTaskbar": "{\"enableBadging\":true}"}
563 /// </summary>
564 static void HandleShowBadgesOnTaskbar(string jsonParams)
565 {
566 try
567 {
568 var param = JObject.Parse(jsonParams);
569 bool enable = param.Value<bool?>("enableBadging") ?? true;
570
571 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"))
572 {
573 if (key != null)
574 {
575 key.SetValue("TaskbarBadges", enable ? 1 : 0, RegistryValueKind.DWord);
576 RefreshTaskbar();
577 }
578 }
579
580 Debug.WriteLine($"Taskbar badges {(enable ? "enabled" : "disabled")}");
581 }
582 catch (Exception ex)
583 {
584 LogError(ex);
585 }
586 }
587
588 /// <summary>
589 /// Shows taskbar on all monitors
590 /// Command: {"DisplayTaskbarOnAllMonitors": "{\"enable\":true}"}
591 /// </summary>
592 static void HandleDisplayTaskbarOnAllMonitors(string jsonParams)
593 {
594 try
595 {
596 var param = JObject.Parse(jsonParams);
597 bool enable = param.Value<bool?>("enable") ?? true;
598
599 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"))
600 {
601 if (key != null)
602 {
603 key.SetValue("MMTaskbarEnabled", enable ? 1 : 0, RegistryValueKind.DWord);
604 RefreshTaskbar();
605 }
606 }
607
608 Debug.WriteLine($"Taskbar on all monitors {(enable ? "enabled" : "disabled")}");
609 }
610 catch (Exception ex)
611 {
612 LogError(ex);
613 }
614 }
615
616 /// <summary>
617 /// Shows seconds in the system tray clock
618 /// Command: {"DisplaySecondsInSystrayClock": "{\"enable\":true}"}
619 /// </summary>
620 static void HandleDisplaySecondsInSystrayClock(string jsonParams)
621 {
622 try
623 {
624 var param = JObject.Parse(jsonParams);
625 bool enable = param.Value<bool?>("enable") ?? true;
626
627 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"))
628 {
629 if (key != null)
630 {
631 key.SetValue("ShowSecondsInSystemClock", enable ? 1 : 0, RegistryValueKind.DWord);
632 RefreshTaskbar();
633 }
634 }
635
636 Debug.WriteLine($"Seconds in clock {(enable ? "shown" : "hidden")}");
637 }
638 catch (Exception ex)
639 {
640 LogError(ex);
641 }
642 }
643
644 #endregion
645
646 #region Mouse Settings
647
648 /// <summary>
649 /// Adjusts mouse cursor speed
650 /// Command: {"MouseCursorSpeed": "{\"speedLevel\":10}"}
651 /// </summary>
652 static void HandleMouseCursorSpeed(string jsonParams)
653 {
654 try
655 {
656 var param = JObject.Parse(jsonParams);
657 int speed = param.Value<int>("speedLevel");
658
659 // Speed range: 1-20 (default 10)
660 speed = Math.Max(1, Math.Min(20, speed));
661
662 SystemParametersInfo(SPI_SETMOUSESPEED, 0, (IntPtr)speed, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
663 Debug.WriteLine($"Mouse speed set to: {speed}");
664 }
665 catch (Exception ex)
666 {
667 LogError(ex);
668 }
669 }
670
671 /// <summary>
672 /// Sets the number of lines to scroll per mouse wheel notch
673 /// Command: {"MouseWheelScrollLines": "{\"scrollLines\":3}"}
674 /// </summary>
675 static void HandleMouseWheelScrollLines(string jsonParams)
676 {
677 try
678 {
679 var param = JObject.Parse(jsonParams);
680 int lines = param.Value<int>("scrollLines");
681
682 lines = Math.Max(1, Math.Min(100, lines));
683
684 SystemParametersInfo(SPI_SETWHEELSCROLLLINES, lines, IntPtr.Zero, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
685 Debug.WriteLine($"Mouse wheel scroll lines set to: {lines}");
686 }
687 catch (Exception ex)
688 {
689 LogError(ex);
690 }
691 }
692
693 /// <summary>
694 /// Sets the primary mouse button
695 /// Command: {"setPrimaryMouseButton": "{\"primaryButton\":\"left\"}"}
696 /// </summary>
697 static void HandleSetPrimaryMouseButton(string jsonParams)
698 {
699 try
700 {
701 var param = JObject.Parse(jsonParams);
702 string button = param.Value<string>("primaryButton");
703 bool leftPrimary = button.Equals("left", StringComparison.OrdinalIgnoreCase);
704
705 SwapMouseButton(leftPrimary ? 0 : 1);
706 Debug.WriteLine($"Primary mouse button set to: {button}");
707 }
708 catch (Exception ex)
709 {
710 LogError(ex);
711 }
712 }
713
714 /// <summary>
715 /// Enables or disables enhanced pointer precision (mouse acceleration)
716 /// Command: {"EnhancePointerPrecision": "{\"enable\":true}"}
717 /// </summary>
718 static void HandleEnhancePointerPrecision(string jsonParams)
719 {
720 try
721 {
722 var param = JObject.Parse(jsonParams);
723 bool enable = param.Value<bool?>("enable") ?? true;
724
725 int[] mouseParams = new int[3];
726 SystemParametersInfo(SPI_GETMOUSE, 0, mouseParams, 0);
727
728 // Set acceleration (third parameter)
729 mouseParams[2] = enable ? 1 : 0;
730
731 SystemParametersInfo(SPI_SETMOUSE, 0, mouseParams, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
732 Debug.WriteLine($"Enhanced pointer precision {(enable ? "enabled" : "disabled")}");
733 }
734 catch (Exception ex)
735 {
736 LogError(ex);
737 }
738 }
739
740 /// <summary>
741 /// Adjusts mouse pointer size
742 /// Command: {"AdjustMousePointerSize": "{\"sizeAdjustment\":\"increase\"}"}
743 /// </summary>
744 static void HandleAdjustMousePointerSize(string jsonParams)
745 {
746 try
747 {
748 var param = JObject.Parse(jsonParams);
749 string adjustment = param.Value<string>("sizeAdjustment");
750
751 // Open mouse pointer settings
752 Process.Start(new ProcessStartInfo
753 {
754 FileName = "ms-settings:easeofaccess-mouse",
755 UseShellExecute = true
756 });
757
758 Debug.WriteLine($"Mouse pointer settings opened for size adjustment");
759 }
760 catch (Exception ex)
761 {
762 LogError(ex);
763 }
764 }
765
766 /// <summary>
767 /// Customizes mouse pointer color
768 /// Command: {"mousePointerCustomization": "{\"color\":\"#FF0000\"}"}
769 /// </summary>
770 static void HandleMousePointerCustomization(string jsonParams)
771 {
772 try
773 {
774 var param = JObject.Parse(jsonParams);
775 string color = param.Value<string>("color");
776
777 // Open mouse pointer settings
778 Process.Start(new ProcessStartInfo
779 {
780 FileName = "ms-settings:easeofaccess-mouse",
781 UseShellExecute = true
782 });
783
784 Debug.WriteLine($"Mouse pointer settings opened for color customization");
785 }
786 catch (Exception ex)
787 {
788 LogError(ex);
789 }
790 }
791
792 #endregion
793
794 #region Touchpad Settings
795
796 /// <summary>
797 /// Enables or disables the touchpad
798 /// Command: {"EnableTouchPad": "{\"enable\":true}"}
799 /// </summary>
800 static void HandleEnableTouchPad(string jsonParams)
801 {
802 try
803 {
804 var param = JObject.Parse(jsonParams);
805 bool enable = param.Value<bool>("enable");
806
807 // Open touchpad settings
808 Process.Start(new ProcessStartInfo
809 {
810 FileName = "ms-settings:devices-touchpad",
811 UseShellExecute = true
812 });
813
814 Debug.WriteLine($"Touchpad settings opened");
815 }
816 catch (Exception ex)
817 {
818 LogError(ex);
819 }
820 }
821
822 /// <summary>
823 /// Adjusts touchpad cursor speed
824 /// Command: {"TouchpadCursorSpeed": "{\"speed\":5}"}
825 /// </summary>
826 static void HandleTouchpadCursorSpeed(string jsonParams)
827 {
828 try
829 {
830 var param = JObject.Parse(jsonParams);
831 int speed = param.Value<int?>("speed") ?? 5;
832
833 // Open touchpad settings
834 Process.Start(new ProcessStartInfo
835 {
836 FileName = "ms-settings:devices-touchpad",
837 UseShellExecute = true
838 });
839
840 Debug.WriteLine($"Touchpad settings opened for speed adjustment");
841 }
842 catch (Exception ex)
843 {
844 LogError(ex);
845 }
846 }
847
848 #endregion
849
850 #region Privacy Settings
851
852 /// <summary>
853 /// Manages microphone access for apps
854 /// Command: {"ManageMicrophoneAccess": "{\"accessSetting\":\"allow\"}"}
855 /// </summary>
856 static void HandleManageMicrophoneAccess(string jsonParams)
857 {
858 try
859 {
860 var param = JObject.Parse(jsonParams);
861 string access = param.Value<string>("accessSetting");
862 bool allow = access.Equals("allow", StringComparison.OrdinalIgnoreCase);
863
864 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\microphone"))
865 {
866 if (key != null)
867 {
868 key.SetValue("Value", allow ? "Allow" : "Deny", RegistryValueKind.String);
869 }
870 }
871
872 Debug.WriteLine($"Microphone access {access}");
873 }
874 catch (Exception ex)
875 {
876 LogError(ex);
877 }
878 }
879
880 /// <summary>
881 /// Manages camera access for apps
882 /// Command: {"ManageCameraAccess": "{\"accessSetting\":\"allow\"}"}
883 /// </summary>
884 static void HandleManageCameraAccess(string jsonParams)
885 {
886 try
887 {
888 var param = JObject.Parse(jsonParams);
889 string access = param.Value<string?>("accessSetting") ?? "allow";
890 bool allow = access.Equals("allow", StringComparison.OrdinalIgnoreCase);
891
892 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam"))
893 {
894 if (key != null)
895 {
896 key.SetValue("Value", allow ? "Allow" : "Deny", RegistryValueKind.String);
897 }
898 }
899
900 Debug.WriteLine($"Camera access {access}");
901 }
902 catch (Exception ex)
903 {
904 LogError(ex);
905 }
906 }
907
908 /// <summary>
909 /// Manages location access for apps
910 /// Command: {"ManageLocationAccess": "{\"accessSetting\":\"allow\"}"}
911 /// </summary>
912 static void HandleManageLocationAccess(string jsonParams)
913 {
914 try
915 {
916 var param = JObject.Parse(jsonParams);
917 string access = param.Value<string?>("accessSetting") ?? "allow";
918 bool allow = access.Equals("allow", StringComparison.OrdinalIgnoreCase);
919
920 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location"))
921 {
922 if (key != null)
923 {
924 key.SetValue("Value", allow ? "Allow" : "Deny", RegistryValueKind.String);
925 }
926 }
927
928 Debug.WriteLine($"Location access {access}");
929 }
930 catch (Exception ex)
931 {
932 LogError(ex);
933 }
934 }
935
936 #endregion
937
938 #region Power Settings
939
940 /// <summary>
941 /// Sets the battery saver activation threshold
942 /// Command: {"BatterySaverActivationLevel": "{\"thresholdValue\":20}"}
943 /// </summary>
944 static void HandleBatterySaverActivationLevel(string jsonParams)
945 {
946 try
947 {
948 var param = JObject.Parse(jsonParams);
949 int threshold = param.Value<int>("thresholdValue");
950
951 threshold = Math.Max(0, Math.Min(100, threshold));
952
953 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Power\BatterySaver"))
954 {
955 if (key != null)
956 {
957 key.SetValue("ActivationThreshold", threshold, RegistryValueKind.DWord);
958 }
959 }
960
961 Debug.WriteLine($"Battery saver threshold set to: {threshold}%");
962 }
963 catch (Exception ex)
964 {
965 LogError(ex);
966 }
967 }
968
969 /// <summary>
970 /// Sets power mode when plugged in
971 /// Command: {"setPowerModePluggedIn": "{\"powerMode\":\"bestPerformance\"}"}
972 /// </summary>
973 static void HandleSetPowerModePluggedIn(string jsonParams)
974 {
975 try
976 {
977 var param = JObject.Parse(jsonParams);
978 string mode = param.Value<string>("powerMode");
979
980 // Open power settings
981 Process.Start(new ProcessStartInfo
982 {
983 FileName = "ms-settings:powersleep",
984 UseShellExecute = true
985 });
986
987 Debug.WriteLine($"Power settings opened for mode adjustment");
988 }
989 catch (Exception ex)
990 {
991 LogError(ex);
992 }
993 }
994
995 /// <summary>
996 /// Sets power mode when on battery
997 /// Command: {"SetPowerModeOnBattery": "{\"mode\":\"balanced\"}"}
998 /// </summary>
999 static void HandleSetPowerModeOnBattery(string jsonParams)
1000 {
1001 try
1002 {
1003 var param = JObject.Parse(jsonParams);
1004 string mode = param.Value<string?>("mode") ?? "balanced";
1005
1006 // Open power settings
1007 Process.Start(new ProcessStartInfo
1008 {
1009 FileName = "ms-settings:powersleep",
1010 UseShellExecute = true
1011 });
1012
1013 Debug.WriteLine($"Power settings opened for battery mode adjustment");
1014 }
1015 catch (Exception ex)
1016 {
1017 LogError(ex);
1018 }
1019 }
1020
1021 #endregion
1022
1023 #region Gaming Settings
1024
1025 /// <summary>
1026 /// Enables or disables Game Mode
1027 /// Command: {"enableGameMode": "{}"}
1028 /// </summary>
1029 static void HandleEnableGameMode(string jsonParams)
1030 {
1031 try
1032 {
1033 // Open gaming settings
1034 Process.Start(new ProcessStartInfo
1035 {
1036 FileName = "ms-settings:gaming-gamemode",
1037 UseShellExecute = true
1038 });
1039
1040 Debug.WriteLine($"Game Mode settings opened");
1041 }
1042 catch (Exception ex)
1043 {
1044 LogError(ex);
1045 }
1046 }
1047
1048 #endregion
1049
1050 #region Accessibility Settings
1051
1052 /// <summary>
1053 /// Enables or disables Narrator
1054 /// Command: {"EnableNarratorAction": "{\"enable\":true}"}
1055 /// </summary>
1056 static void HandleEnableNarratorAction(string jsonParams)
1057 {
1058 try
1059 {
1060 var param = JObject.Parse(jsonParams);
1061 bool enable = param.Value<bool?>("enable") ?? true;
1062
1063 if (enable)
1064 {
1065 Process.Start("narrator.exe");
1066 }
1067 else
1068 {
1069 // Kill narrator process
1070 var processes = Process.GetProcessesByName("Narrator");
1071 foreach (var p in processes)
1072 {
1073 p.Kill();
1074 }
1075 }
1076
1077 Debug.WriteLine($"Narrator {(enable ? "started" : "stopped")}");
1078 }
1079 catch (Exception ex)
1080 {
1081 LogError(ex);
1082 }
1083 }
1084
1085 /// <summary>
1086 /// Enables or disables Magnifier
1087 /// Command: {"EnableMagnifier": "{\"enable\":true}"}
1088 /// </summary>
1089 static void HandleEnableMagnifier(string jsonParams)
1090 {
1091 try
1092 {
1093 var param = JObject.Parse(jsonParams);
1094 bool enable = param.Value<bool?>("enable") ?? true;
1095
1096 if (enable)
1097 {
1098 Process.Start("magnify.exe");
1099 }
1100 else
1101 {
1102 // Kill magnifier process
1103 var processes = Process.GetProcessesByName("Magnify");
1104 foreach (var p in processes)
1105 {
1106 p.Kill();
1107 }
1108 }
1109
1110 Debug.WriteLine($"Magnifier {(enable ? "started" : "stopped")}");
1111 }
1112 catch (Exception ex)
1113 {
1114 LogError(ex);
1115 }
1116 }
1117
1118 /// <summary>
1119 /// Enables or disables Sticky Keys
1120 /// Command: {"enableStickyKeys": "{\"enable\":true}"}
1121 /// </summary>
1122 static void HandleEnableStickyKeysAction(string jsonParams)
1123 {
1124 try
1125 {
1126 var param = JObject.Parse(jsonParams);
1127 bool enable = param.Value<bool>("enable");
1128
1129 using (var key = Registry.CurrentUser.CreateSubKey(@"Control Panel\Accessibility\StickyKeys"))
1130 {
1131 if (key != null)
1132 {
1133 key.SetValue("Flags", enable ? "510" : "506", RegistryValueKind.String);
1134 }
1135 }
1136
1137 Debug.WriteLine($"Sticky Keys {(enable ? "enabled" : "disabled")}");
1138 }
1139 catch (Exception ex)
1140 {
1141 LogError(ex);
1142 }
1143 }
1144
1145 /// <summary>
1146 /// Enables or disables Filter Keys
1147 /// Command: {"EnableFilterKeysAction": "{\"enable\":true}"}
1148 /// </summary>
1149 static void HandleEnableFilterKeysAction(string jsonParams)
1150 {
1151 try
1152 {
1153 var param = JObject.Parse(jsonParams);
1154 bool enable = param.Value<bool?>("enable") ?? true;
1155
1156 using (var key = Registry.CurrentUser.CreateSubKey(@"Control Panel\Accessibility\Keyboard Response"))
1157 {
1158 if (key != null)
1159 {
1160 key.SetValue("Flags", enable ? "2" : "126", RegistryValueKind.String);
1161 }
1162 }
1163
1164 Debug.WriteLine($"Filter Keys {(enable ? "enabled" : "disabled")}");
1165 }
1166 catch (Exception ex)
1167 {
1168 LogError(ex);
1169 }
1170 }
1171
1172 /// <summary>
1173 /// Enables or disables mono audio
1174 /// Command: {"MonoAudioToggle": "{\"enable\":true}"}
1175 /// </summary>
1176 static void HandleMonoAudioToggle(string jsonParams)
1177 {
1178 try
1179 {
1180 var param = JObject.Parse(jsonParams);
1181 bool enable = param.Value<bool?>("enable") ?? true;
1182
1183 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Multimedia\Audio"))
1184 {
1185 if (key != null)
1186 {
1187 key.SetValue("AccessibilityMonoMixState", enable ? 1 : 0, RegistryValueKind.DWord);
1188 }
1189 }
1190
1191 Debug.WriteLine($"Mono audio {(enable ? "enabled" : "disabled")}");
1192 }
1193 catch (Exception ex)
1194 {
1195 LogError(ex);
1196 }
1197 }
1198
1199 #endregion
1200
1201 #region File Explorer Settings
1202
1203 /// <summary>
1204 /// Shows or hides file extensions in File Explorer
1205 /// Command: {"ShowFileExtensions": "{\"enable\":true}"}
1206 /// </summary>
1207 static void HandleShowFileExtensions(string jsonParams)
1208 {
1209 try
1210 {
1211 var param = JObject.Parse(jsonParams);
1212 bool enable = param.Value<bool?>("enable") ?? true;
1213
1214 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"))
1215 {
1216 if (key != null)
1217 {
1218 // 0 = show extensions, 1 = hide extensions
1219 key.SetValue("HideFileExt", enable ? 0 : 1, RegistryValueKind.DWord);
1220 RefreshExplorer();
1221 }
1222 }
1223
1224 Debug.WriteLine($"File extensions {(enable ? "shown" : "hidden")}");
1225 }
1226 catch (Exception ex)
1227 {
1228 LogError(ex);
1229 }
1230 }
1231
1232 /// <summary>
1233 /// Shows or hides hidden and system files in File Explorer
1234 /// Command: {"ShowHiddenAndSystemFiles": "{\"enable\":true}"}
1235 /// </summary>
1236 static void HandleShowHiddenAndSystemFiles(string jsonParams)
1237 {
1238 try
1239 {
1240 var param = JObject.Parse(jsonParams);
1241 bool enable = param.Value<bool?>("enable") ?? true;
1242
1243 using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"))
1244 {
1245 if (key != null)
1246 {
1247 // 1 = show hidden files, 2 = don't show hidden files
1248 key.SetValue("Hidden", enable ? 1 : 2, RegistryValueKind.DWord);
1249 // Show protected OS files
1250 key.SetValue("ShowSuperHidden", enable ? 1 : 0, RegistryValueKind.DWord);
1251 RefreshExplorer();
1252 }
1253 }
1254
1255 Debug.WriteLine($"Hidden files {(enable ? "shown" : "hidden")}");
1256 }
1257 catch (Exception ex)
1258 {
1259 LogError(ex);
1260 }
1261 }
1262
1263 #endregion
1264
1265 #region Time & Region Settings
1266
1267 /// <summary>
1268 /// Enables or disables automatic time synchronization
1269 /// Command: {"AutomaticTimeSettingAction": "{\"enableAutoTimeSync\":true}"}
1270 /// </summary>
1271 static void HandleAutomaticTimeSettingAction(string jsonParams)
1272 {
1273 try
1274 {
1275 var param = JObject.Parse(jsonParams);
1276 bool enable = param.Value<bool>("enableAutoTimeSync");
1277
1278 // Open time settings
1279 Process.Start(new ProcessStartInfo
1280 {
1281 FileName = "ms-settings:dateandtime",
1282 UseShellExecute = true
1283 });
1284
1285 Debug.WriteLine($"Time settings opened for auto-sync configuration");
1286 }
1287 catch (Exception ex)
1288 {
1289 LogError(ex);
1290 }
1291 }
1292
1293 /// <summary>
1294 /// Enables or disables automatic DST adjustment
1295 /// Command: {"AutomaticDSTAdjustment": "{\"enable\":true}"}
1296 /// </summary>
1297 static void HandleAutomaticDSTAdjustment(string jsonParams)
1298 {
1299 try
1300 {
1301 var param = JObject.Parse(jsonParams);
1302 bool enable = param.Value<bool?>("enable") ?? true;
1303
1304 using (var key = Registry.LocalMachine.CreateSubKey(@"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"))
1305 {
1306 if (key != null)
1307 {
1308 key.SetValue("DynamicDaylightTimeDisabled", enable ? 0 : 1, RegistryValueKind.DWord);
1309 }
1310 }
1311
1312 Debug.WriteLine($"Automatic DST adjustment {(enable ? "enabled" : "disabled")}");
1313 }
1314 catch (Exception ex)
1315 {
1316 LogError(ex);
1317 }
1318 }
1319
1320 #endregion
1321
1322 #region Focus Assist Settings
1323
1324 /// <summary>
1325 /// Enables or disables Focus Assist (Quiet Hours)
1326 /// Command: {"EnableQuietHours": "{\"startHour\":22,\"endHour\":7}"}
1327 /// </summary>
1328 static void HandleEnableQuietHours(string jsonParams)
1329 {
1330 try
1331 {
1332 var param = JObject.Parse(jsonParams);
1333 int startHour = param.Value<int?>("startHour") ?? 22;
1334 int endHour = param.Value<int?>("endHour") ?? 7;
1335
1336 // Open Focus Assist settings
1337 Process.Start(new ProcessStartInfo
1338 {
1339 FileName = "ms-settings:quiethours",
1340 UseShellExecute = true
1341 });
1342
1343 Debug.WriteLine($"Focus Assist settings opened");
1344 }
1345 catch (Exception ex)
1346 {
1347 LogError(ex);
1348 }
1349 }
1350
1351 #endregion
1352
1353 #region Multi-Monitor Settings
1354
1355 /// <summary>
1356 /// Remembers window locations based on monitor configuration
1357 /// Command: {"RememberWindowLocations": "{\"enable\":true}"}
1358 /// </summary>
1359 static void HandleRememberWindowLocationsAction(string jsonParams)
1360 {
1361 try
1362 {
1363 var param = JObject.Parse(jsonParams);
1364 bool enable = param.Value<bool>("enable");
1365
1366 // This is handled by Windows automatically, but we can open display settings
1367 Process.Start(new ProcessStartInfo
1368 {
1369 FileName = "ms-settings:display",
1370 UseShellExecute = true
1371 });
1372
1373 Debug.WriteLine($"Display settings opened for window location management");
1374 }
1375 catch (Exception ex)
1376 {
1377 LogError(ex);
1378 }
1379 }
1380
1381 /// <summary>
1382 /// Minimizes windows when a monitor is disconnected
1383 /// Command: {"MinimizeWindowsOnMonitorDisconnectAction": "{\"enable\":true}"}
1384 /// </summary>
1385 static void HandleMinimizeWindowsOnMonitorDisconnectAction(string jsonParams)
1386 {
1387 try
1388 {
1389 var param = JObject.Parse(jsonParams);
1390 bool enable = param.Value<bool?>("enable") ?? true;
1391
1392 // Open display settings
1393 Process.Start(new ProcessStartInfo
1394 {
1395 FileName = "ms-settings:display",
1396 UseShellExecute = true
1397 });
1398
1399 Debug.WriteLine($"Display settings opened for disconnect behavior");
1400 }
1401 catch (Exception ex)
1402 {
1403 LogError(ex);
1404 }
1405 }
1406
1407 #endregion
1408
1409 #region Helper Methods
1410
1411 /// <summary>
1412 /// Gets the current brightness level
1413 /// </summary>
1414 static byte GetCurrentBrightness()
1415 {
1416 try
1417 {
1418 using (var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\SettingSync\Settings\SystemSettings\Brightness"))
1419 {
1420 if (key != null)
1421 {
1422 object value = key.GetValue("Data");
1423 if (value is byte[] data && data.Length > 0)
1424 {
1425 return data[0];
1426 }
1427 }
1428 }
1429 }
1430 catch { }
1431
1432 return 50; // Default to 50% if unable to read
1433 }
1434
1435 /// <summary>
1436 /// Sets the brightness level
1437 /// </summary>
1438 static void SetBrightness(byte brightness)
1439 {
1440 try
1441 {
1442 // Use WMI to set brightness
1443 using (var searcher = new System.Management.ManagementObjectSearcher("root\\WMI", "SELECT * FROM WmiMonitorBrightnessMethods"))
1444 {
1445 using (var objectCollection = searcher.Get())
1446 {
1447 foreach (System.Management.ManagementObject obj in objectCollection)
1448 {
1449 obj.InvokeMethod("WmiSetBrightness", new object[] { 1, brightness });
1450 }
1451 }
1452 }
1453 }
1454 catch (Exception ex)
1455 {
1456 Debug.WriteLine($"Failed to set brightness: {ex.Message}");
1457 }
1458 }
1459
1460 /// <summary>
1461 /// Sets DPI scaling percentage
1462 /// </summary>
1463 static void SetDpiScaling(int percentage)
1464 {
1465 try
1466 {
1467 // Open display settings for DPI adjustment
1468 Process.Start(new ProcessStartInfo
1469 {
1470 FileName = "ms-settings:display",
1471 UseShellExecute = true
1472 });
1473 }
1474 catch (Exception ex)
1475 {
1476 Debug.WriteLine($"Failed to set DPI scaling: {ex.Message}");
1477 }
1478 }
1479
1480 /// <summary>
1481 /// Refreshes the taskbar to apply changes
1482 /// </summary>
1483 static void RefreshTaskbar()
1484 {
1485 try
1486 {
1487 // Send a broadcast message to refresh the explorer
1488 SendNotifyMessage(HWND_BROADCAST, WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero);
1489 }
1490 catch { }
1491 }
1492
1493 /// <summary>
1494 /// Refreshes File Explorer to apply changes
1495 /// </summary>
1496 static void RefreshExplorer()
1497 {
1498 try
1499 {
1500 SendNotifyMessage(HWND_BROADCAST, WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero);
1501
1502 // Alternative: restart explorer
1503 // var processes = Process.GetProcessesByName("explorer");
1504 // foreach (var p in processes) p.Kill();
1505 // Process.Start("explorer.exe");
1506 }
1507 catch { }
1508 }
1509
1510 /// <summary>
1511 /// Sets a registry value
1512 /// </summary>
1513 static void SetRegistryValue(string keyPath, string valueName, object value)
1514 {
1515 try
1516 {
1517 Registry.SetValue(keyPath, valueName, value);
1518 }
1519 catch (Exception ex)
1520 {
1521 Debug.WriteLine($"Failed to set registry value: {ex.Message}");
1522 }
1523 }
1524
1525 #endregion
1526
1527 #region Win32 API Declarations for Settings
1528
1529 // SystemParametersInfo constants (additional ones not in AutoShell_Win32.cs)
1530 const int SPI_SETMOUSESPEED = 0x0071;
1531 const int SPI_GETMOUSE = 0x0003;
1532 const int SPI_SETMOUSE = 0x0004;
1533 const int SPI_SETWHEELSCROLLLINES = 0x0069;
1534 // Note: SPIF_UPDATEINIFILE, SPIF_SENDCHANGE, WM_SETTINGCHANGE, HWND_BROADCAST
1535 // are already defined in AutoShell_Win32.cs
1536
1537 [DllImport("user32.dll", SetLastError = true)]
1538 static extern bool SystemParametersInfo(int uiAction, int uiParam, IntPtr pvParam, int fWinIni);
1539
1540 [DllImport("user32.dll", SetLastError = true)]
1541 static extern bool SystemParametersInfo(int uiAction, int uiParam, int[] pvParam, int fWinIni);
1542
1543 [DllImport("user32.dll")]
1544 static extern bool SwapMouseButton(int fSwap);
1545
1546 [DllImport("user32.dll", CharSet = CharSet.Auto)]
1547 static extern IntPtr SendNotifyMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
1548
1549 #endregion
1550}
1551