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.

280 lines
13 KiB

9 months ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.IO.Compression;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Net.Http;
  9. using System.Runtime.InteropServices;
  10. using System.Runtime.InteropServices.ComTypes;
  11. using System.Security.AccessControl;
  12. using System.ServiceProcess;
  13. using System.Text;
  14. using System.Text.RegularExpressions;
  15. using System.Threading;
  16. using amecs.Actions;
  17. using Ameliorated.ConsoleUtils;
  18. using IWshRuntimeLibrary;
  19. using File = System.IO.File;
  20. namespace amecs.Extra
  21. {
  22. public class NVCP
  23. {
  24. private static readonly string DestinationDir = Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES%\NVIDIA Control Panel");
  25. public static bool Install(string NVCP) => amecs.RunBasicAction("Installing NVIDIA Control Panel", "NVIDIA Control Panel installed successfully", () =>
  26. {
  27. Thread.Sleep(4000);
  28. try
  29. {
  30. foreach (var proc in Process.GetProcessesByName("nvcplui"))
  31. proc.Kill();
  32. } catch
  33. {
  34. }
  35. if (Directory.Exists(DestinationDir))
  36. Directory.Delete(DestinationDir, true);
  37. Directory.Move(NVCP, DestinationDir);
  38. var di = new DirectoryInfo(DestinationDir);
  39. var sec = di.GetAccessControl();
  40. sec.AddAccessRule(new FileSystemAccessRule("Administrators", FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
  41. sec.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.ReadAndExecute, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
  42. di.SetAccessControl(sec);
  43. Config();
  44. });
  45. public static bool InstallFromNetwork()
  46. {
  47. try
  48. {
  49. foreach (var proc in Process.GetProcessesByName("nvcplui"))
  50. proc.Kill();
  51. } catch
  52. {
  53. }
  54. if (Directory.Exists(DestinationDir))
  55. Directory.Delete(DestinationDir, true);
  56. var choice = new ChoicePrompt() {Text = "NVIDIA Control Panel must be downloaded\r\nContinue? (Y/N): "}.Start();
  57. if (!choice.HasValue || choice == 1)
  58. return false;
  59. string link;
  60. string filter;
  61. string size;
  62. ConsoleTUI.OpenFrame.WriteCentered("\r\nFetching download link");
  63. try
  64. {
  65. using (new ConsoleUtils.LoadingIndicator(true))
  66. {
  67. using (HttpClient client = new HttpClient())
  68. {
  69. using (HttpResponseMessage response = client.GetAsync("https://git.ameliorated.info/Styris/amecs/src/branch/master/links.txt").Result)
  70. {
  71. using (HttpContent content = response.Content)
  72. {
  73. string result = content.ReadAsStringAsync().Result;
  74. var line = result.SplitByLine().First(x => x.Contains("NVIDIA-Control-Panel = "));
  75. var split = line.Split('|');
  76. link = split[1];
  77. filter = split[3];
  78. if (link == "REMOVED")
  79. throw new Exception("Link is no longer available.");
  80. }
  81. }
  82. var values = new Dictionary<string, string>
  83. {
  84. { "type", "url" },
  85. { "url", link },
  86. { "ring", "Retail" }
  87. };
  88. var request = new FormUrlEncodedContent(values);
  89. using (HttpResponseMessage response = client.PostAsync("https://store.rg-adguard.net/api/GetFiles", request).Result)
  90. {
  91. using (HttpContent content = response.Content)
  92. {
  93. string result = content.ReadAsStringAsync().Result;
  94. var regex = new Regex($".*{filter}.*");
  95. var match = regex.Match(result).Value;
  96. var split = match.Split('"');
  97. link = split[3];
  98. size = split[12].Remove(0, 1).Remove(split[12].Length - 11);
  99. if (!size.Contains("MB") && !size.Contains("KB") && !size.Contains("GB"))
  100. size = "0 MB";
  101. }
  102. }
  103. }
  104. }
  105. } catch (Exception e)
  106. {
  107. Console.WriteLine();
  108. ConsoleTUI.OpenFrame.Close("Could not fetch link: " + e.Message, ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "});
  109. return false;
  110. }
  111. var temp = Environment.ExpandEnvironmentVariables(@"%TEMP%\[amecs]-NVCP-" + new Random().Next(0, 9999) + ".zip");
  112. try
  113. {
  114. ConsoleTUI.OpenFrame.WriteCenteredLine($"\r\nDownloading NVIDIA Control Panel ({size})");
  115. using (WebClient wc = new WebClient())
  116. {
  117. var stdout = GetStdHandle(-11);
  118. var maxHashTags = (ConsoleTUI.OpenFrame.DisplayWidth - 5);
  119. wc.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e)
  120. {
  121. var currentHashTags = (int)Math.Ceiling(Math.Min(((double)e.ProgressPercentage / 100) * maxHashTags, maxHashTags));
  122. var spaces = maxHashTags - currentHashTags + (4 - e.ProgressPercentage.ToString().Length);
  123. var sb = new StringBuilder(new string('#', currentHashTags) + new string(' ', spaces) + e.ProgressPercentage + "%");
  124. uint throwaway;
  125. WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)Console.CursorTop), out throwaway);
  126. };
  127. var task = wc.DownloadFileTaskAsync(new Uri(link), temp);
  128. task.Wait();
  129. Thread.Sleep(100);
  130. var sb = new StringBuilder(new string('#', maxHashTags) + " 100%");
  131. uint throwaway;
  132. WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)Console.CursorTop), out throwaway);
  133. }
  134. Console.WriteLine();
  135. ZipFile.ExtractToDirectory(temp, DestinationDir);
  136. if (!File.Exists(Path.Combine(DestinationDir, "nvcplui.exe")))
  137. {
  138. try { Directory.Delete(DestinationDir, true);} catch {}
  139. Console.WriteLine();
  140. ConsoleTUI.OpenFrame.Close("Download is missing critical executable.", ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "});
  141. return false;
  142. }
  143. Config();
  144. } catch (Exception e)
  145. {
  146. Console.WriteLine();
  147. ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "});
  148. return false;
  149. }
  150. Console.WriteLine();
  151. ConsoleTUI.OpenFrame.Close("NVIDIA Control Panel installed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt() {AnyKey = true, Text = "Press any key to return to the Menu: "});
  152. return true;
  153. }
  154. public static bool Uninstall() => amecs.RunBasicAction("Uninstalling NVIDIA Control Panel", "NVIDIA Control Panel uninstalled successfully", () =>
  155. {
  156. var linkPath = Environment.ExpandEnvironmentVariables(@"%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\NVIDIA Control Panel.lnk");
  157. if (File.Exists(linkPath))
  158. File.Delete(linkPath);
  159. Directory.Delete(DestinationDir, true);
  160. Thread.Sleep(2000);
  161. });
  162. public static void Config()
  163. {
  164. try
  165. {
  166. new Reg.Value() { KeyName = @"HKLM\System\CurrentControlSet\Services\nvlddmkm\Global\NVTweak", ValueName = "DisableStoreNvCplNotifications", Type = Reg.RegistryValueType.REG_DWORD, Data = 1 }.Apply();
  167. } catch (Exception e)
  168. {
  169. ConsoleTUI.ShowErrorBox("Could not disable NVIDIA Microsoft Store notification: " + e.ToString(), "Error");
  170. }
  171. var linkPath = Environment.ExpandEnvironmentVariables(@"%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\NVIDIA Control Panel.lnk");
  172. if (File.Exists(linkPath))
  173. File.Delete(linkPath);
  174. try
  175. {
  176. IShellLink link = (IShellLink)new ShellLink();
  177. link.SetDescription("NVIDIA Control Panel");
  178. link.SetPath(Path.Combine(DestinationDir, "nvcplui.exe"));
  179. IPersistFile file = (IPersistFile)link;
  180. file.Save(linkPath, false);
  181. } catch
  182. {
  183. WshShell shell = new WshShell();
  184. IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(linkPath);
  185. shortcut.Description = "NVIDIA Control Panel";
  186. shortcut.TargetPath = Path.Combine(DestinationDir, "nvcplui.exe");
  187. shortcut.Save();
  188. }
  189. new Reg.Value() { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\NVDisplay.ContainerLocalSystem", ValueName = "Start", Type = Reg.RegistryValueType.REG_DWORD, Data = 2 }.Apply();
  190. try { ServiceController.GetServices().First(x => x.ServiceName.Equals("NVDisplay.ContainerLocalSystem")).Start(); } catch (Exception e) { }
  191. }
  192. [DllImport("kernel32.dll", SetLastError = true)]
  193. internal static extern bool WriteConsoleOutputCharacter(IntPtr hConsoleOutput, StringBuilder lpCharacter, uint nLength, COORD dwWriteCoord, out uint lpNumberOfCharsWritten);
  194. [DllImport("kernel32.dll", SetLastError = true)]
  195. static extern IntPtr GetStdHandle(int nStdHandle);
  196. [StructLayout(LayoutKind.Sequential)]
  197. public struct COORD
  198. {
  199. public short X;
  200. public short Y;
  201. public COORD(short X, short Y)
  202. {
  203. this.X = X;
  204. this.Y = Y;
  205. }
  206. };
  207. }
  208. [ComImport]
  209. [Guid("00021401-0000-0000-C000-000000000046")]
  210. internal class ShellLink
  211. {
  212. }
  213. [ComImport]
  214. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  215. [Guid("000214F9-0000-0000-C000-000000000046")]
  216. internal interface IShellLink
  217. {
  218. void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags);
  219. void GetIDList(out IntPtr ppidl);
  220. void SetIDList(IntPtr pidl);
  221. void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
  222. void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
  223. void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
  224. void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
  225. void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
  226. void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
  227. void GetHotkey(out short pwHotkey);
  228. void SetHotkey(short wHotkey);
  229. void GetShowCmd(out int piShowCmd);
  230. void SetShowCmd(int iShowCmd);
  231. void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
  232. void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
  233. void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
  234. void Resolve(IntPtr hwnd, int fFlags);
  235. void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
  236. }
  237. }