Script for automating a large assortment of AME related actions
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
11 KiB

  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Security.Principal;
  5. using System.Threading;
  6. using amecs.Misc;
  7. using Ameliorated.ConsoleUtils;
  8. using Microsoft.Win32;
  9. namespace amecs.Actions
  10. {
  11. public class Deameliorate
  12. {
  13. private static string _mountedPath;
  14. private static string _winVer;
  15. private static string _win11Setup = "";
  16. private static bool _win11 = Environment.OSVersion.Version.Build >= 22000;
  17. private const string ExplorerPatcherId = "D17F1E1A-5919-4427-8F89-A1A8503CA3EB";
  18. public static bool DeAme()
  19. {
  20. if (new ChoicePrompt()
  21. {
  22. Text = @"
  23. This will de-ameliorate by reinstalling Windows.
  24. Although user data should be kept, we strongly recommend
  25. making backups of any important user data.
  26. Continue? (Y/N): "
  27. }.Start().Value == 1) return true;
  28. Program.Frame.Clear();
  29. (_mountedPath, _, _winVer, _, _) = SelectWindowsImage.GetMediaPath();
  30. if (_mountedPath == null) return false;
  31. if (new ChoicePrompt {Text = $"\r\nYour Windows image is {_winVer}. Continue? (Y/N): "}.Start().Value == 1)
  32. return true;
  33. var fc = Console.ForegroundColor;
  34. Console.ForegroundColor = ConsoleColor.Yellow;
  35. string userSid = null;
  36. try
  37. {
  38. NSudo.GetSystemPrivilege();
  39. NSudo.RunAsUser(() =>
  40. {
  41. userSid = WindowsIdentity.GetCurrent().User.ToString();
  42. });
  43. }
  44. catch
  45. {
  46. // do nothing
  47. }
  48. try
  49. {
  50. ConsoleTUI.OpenFrame.WriteCentered("\r\nUninstalling AME-installed UI software...");
  51. string openShellId = null;
  52. var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
  53. foreach (var item in key.GetSubKeyNames())
  54. {
  55. try
  56. {
  57. if (((string)key.OpenSubKey(item).GetValue("DisplayName")).Equals("Open-Shell"))
  58. openShellId = item;
  59. }
  60. catch
  61. {
  62. // do nothing
  63. }
  64. }
  65. if (openShellId != null)
  66. {
  67. ConsoleTUI.OpenFrame.WriteCentered("\r\nUninstalling Open-Shell...");
  68. Process.Start("MsiExec.exe", $"/X{openShellId} /quiet")?.WaitForExit();
  69. if (userSid != null)
  70. {
  71. var appData = (string)Registry.Users.OpenSubKey(userSid + @"\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders").GetValue("AppData");
  72. if (Directory.Exists(Path.Combine(appData, "OpenShell")))
  73. Directory.Delete(Path.Combine(appData, "OpenShell"), true);
  74. }
  75. }
  76. var epSetupPath = $@"{Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)}\ExplorerPatcher\ep_setup.exe";
  77. if (File.Exists(epSetupPath))
  78. {
  79. ConsoleTUI.OpenFrame.WriteCentered("\r\nUninstalling ExplorerPatcher...");
  80. var winlogon = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true);
  81. winlogon?.SetValue("AutoRestartShell", 0);
  82. // kill processes that the files use
  83. foreach (var processName in new[] {"explorer.exe", "rundll32.exe", "dllhost.exe", "ShellExperienceHost.exe", "StartMenuExperienceHost.exe"})
  84. {
  85. foreach (var process in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(processName)))
  86. {
  87. process.Kill();
  88. process.WaitForExit();
  89. }
  90. }
  91. // delete DWM service that removes rounded corners
  92. Process.Start("sc", $"stop \"ep_dwm_{ExplorerPatcherId}\"")?.WaitForExit();
  93. Process.Start("sc", $"delete \"ep_dwm_{ExplorerPatcherId}\"")?.WaitForExit();
  94. // remove registered DLL
  95. var explorerPatcherDllPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "ExplorerPatcher", "ExplorerPatcher.amd64.dll");
  96. Process.Start("regsvr32.exe", $"/s /u \"{explorerPatcherDllPath}\"")?.WaitForExit();
  97. // delete files
  98. foreach (var file in new[]
  99. {
  100. Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
  101. @"SystemApps\ShellExperienceHost_cw5n1h2txyewy\dxgi.dll"),
  102. Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
  103. @"SystemApps\ShellExperienceHost_cw5n1h2txyewy\wincorlib.dll"),
  104. Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
  105. @"SystemApps\ShellExperienceHost_cw5n1h2txyewy\wincorlib_orig.dll"),
  106. Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
  107. @"SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\dxgi.dll"),
  108. Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
  109. @"SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\wincorlib.dll"),
  110. Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
  111. @"SystemApps\Microsoft.Windows.StartMenuExperienceHost_cw5n1h2txyewy\wincorlib_orig.dll"),
  112. Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
  113. "dxgi.dll")
  114. })
  115. {
  116. if (File.Exists(file)) File.Delete(file);
  117. }
  118. foreach (var folder in new[]
  119. {
  120. Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
  121. "ExplorerPatcher"),
  122. Path.Combine(
  123. Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
  124. @"Microsoft\Windows\Start Menu\Programs\ExplorerPatcher")
  125. })
  126. {
  127. if (Directory.Exists(folder)) Directory.Delete(folder, true);
  128. }
  129. winlogon?.SetValue("AutoRestartShell", 1);
  130. }
  131. Program.Frame.Clear();
  132. } catch (Exception e)
  133. {
  134. ConsoleTUI.OpenFrame.Close(
  135. "Error when uninstalling software: " + e.Message,
  136. ConsoleColor.Red, Console.BackgroundColor,
  137. new ChoicePrompt { AnyKey = true, Text = "Press any key to continue anyways: " });
  138. Program.Frame.Clear();
  139. ConsoleTUI.OpenFrame.WriteCentered("\r\nContinuing without uninstalling software...\r\n");
  140. }
  141. // restart Explorer
  142. if (Process.GetProcessesByName("explorer").Length == 0)
  143. NSudo.RunProcessAsUser(NSudo.GetUserToken(), "explorer.exe", "", 0);
  144. // all policies are cleared as a user that's de-ameliorating is unlikely to have their own policies in the first place
  145. // also clear ExplorerPatcher Registry entries
  146. ConsoleTUI.OpenFrame.WriteCentered("\r\nClearing policies...");
  147. foreach (var keyPath in new[] {
  148. $@"HKU\{userSid}\Software\Microsoft\Windows\CurrentVersion\Policies",
  149. $@"HKU\{userSid}\Software\Policies",
  150. $@"HKU\{userSid}\Software\ExplorerPatcher",
  151. $@"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{{ExplorerPatcherId}}}_ExplorerPatcher",
  152. @"HKLM\Software\Microsoft\Windows\CurrentVersion\Policies",
  153. @"HKLM\Software\Policies",
  154. @"HKLM\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Policies"
  155. })
  156. {
  157. var hive = RegistryHive.LocalMachine;
  158. if (keyPath.StartsWith("HKU"))
  159. hive = RegistryHive.Users;
  160. var baseKey = RegistryKey.OpenBaseKey(hive, RegistryView.Default);
  161. var subKeyPath = keyPath.Substring(keyPath.IndexOf('\\') + 1);
  162. var key = baseKey.OpenSubKey(subKeyPath, true);
  163. if (key == null) continue;
  164. try
  165. {
  166. baseKey.DeleteSubKeyTree(subKeyPath);
  167. }
  168. catch
  169. {
  170. // do nothing - some values might fail, but almost all are deleted
  171. }
  172. key.Close();
  173. }
  174. Thread.Sleep(3000);
  175. Program.Frame.Clear();
  176. ConsoleTUI.OpenFrame.WriteCentered("\r\nCompleted initial setup!", ConsoleColor.Green);
  177. if (_win11)
  178. {
  179. ConsoleTUI.OpenFrame.WriteCentered("\r\nWindows Setup will display as 'Windows Server,' but it's not actually installing Windows Server and is only set as such to bypass hardware requirements.");
  180. Console.WriteLine();
  181. }
  182. ConsoleTUI.OpenFrame.WriteCentered("\r\nWaiting 10 seconds and starting Windows Setup...");
  183. Console.ForegroundColor = fc;
  184. Thread.Sleep(10000);
  185. Console.WriteLine();
  186. try
  187. {
  188. if (_win11) _win11Setup = "/Product Server";
  189. Process.Start(Path.Combine(_mountedPath, "setup.exe"), $"/Auto Upgrade /DynamicUpdate Disable {_win11Setup}");
  190. } catch (Exception e)
  191. {
  192. ConsoleTUI.OpenFrame.Close(
  193. $"There was an error when trying to run the Windows Setup: {e}\r\nTry running the Windows Setup manually from File Explorer.",
  194. ConsoleColor.Red, Console.BackgroundColor,
  195. new ChoicePrompt { AnyKey = true, Text = $"Press any key to exit: " });
  196. return false;
  197. }
  198. ConsoleTUI.OpenFrame.Close(
  199. "Completed, Windows Setup should have started.",
  200. ConsoleColor.Cyan, Console.BackgroundColor,
  201. new ChoicePrompt { AnyKey = true, Text = $"Press any key to go back: " });
  202. return true;
  203. }
  204. }
  205. }