PageRenderTime 32ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Kweh.Core/Win32/RegistryUtil.cs

https://gitlab.com/nerdymishka/kweh
C# | 320 lines | 280 code | 39 blank | 1 comment | 52 complexity | b47d73449bc0646243c2ccd77df77ee3 MD5 | raw file
  1. using Microsoft.Win32;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. namespace BadMishka.Kweh.Win32
  8. {
  9. public static class RegistryUtil
  10. {
  11. public static RegistryKey FindUninstallKey(string displayName, Func<string, string, bool> comparison = null, string sid = null)
  12. {
  13. if (comparison == null)
  14. comparison = (left, right) =>
  15. {
  16. if (string.IsNullOrWhiteSpace(right))
  17. return false;
  18. return left.StartsWith(right);
  19. };
  20. var list = new List<string>()
  21. {
  22. @"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
  23. @"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
  24. @"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
  25. @"HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
  26. $"HKU:\\{sid}\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
  27. $"HKU:\\{sid}\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
  28. };
  29. var noSid = string.IsNullOrWhiteSpace(sid);
  30. foreach(var subKeyName in list)
  31. {
  32. if (subKeyName.StartsWith("HKU") && noSid)
  33. continue;
  34. var subKey = OpenSubKey(subKeyName);
  35. if (subKey == null)
  36. continue;
  37. var subKeyNames = subKey.GetSubKeyNames();
  38. foreach(var guidSubKeyName in subKeyNames)
  39. {
  40. var guidSubKey = subKey.OpenSubKey(guidSubKeyName);
  41. var productDisplayName = guidSubKey.GetValue("DisplayName") as string;
  42. if (productDisplayName == null)
  43. continue;
  44. if (comparison(productDisplayName, displayName))
  45. return guidSubKey;
  46. }
  47. }
  48. return null;
  49. }
  50. public static RegistryKey FindUninstallKey(Guid productId, Func<string, string, bool> comparison = null, string sid = null)
  51. {
  52. if (comparison == null)
  53. comparison = (left, right) =>
  54. {
  55. if (string.IsNullOrWhiteSpace(right))
  56. return false;
  57. return left.StartsWith(right);
  58. };
  59. var list = new List<string>()
  60. {
  61. @"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
  62. @"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
  63. @"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
  64. @"HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
  65. $"HKU:\\{sid}\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
  66. $"HKU:\\{sid}\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
  67. };
  68. var noSid = string.IsNullOrWhiteSpace(sid);
  69. foreach (var subKeyName in list)
  70. {
  71. if (subKeyName.StartsWith("HKU") && noSid)
  72. continue;
  73. var subKey = OpenSubKey(subKeyName + "\\" + productId.ToString());
  74. if (subKey != null)
  75. return subKey;
  76. }
  77. return null;
  78. }
  79. public static RegistryKey OpenSubKey(string registryPath)
  80. {
  81. if (string.IsNullOrWhiteSpace(registryPath))
  82. throw new ArgumentNullException(nameof(registryPath));
  83. if(!registryPath.Contains(":"))
  84. throw new ArgumentException("registryPath is missing registry drive", nameof(registryPath));
  85. var delimiterIndex = registryPath.IndexOf(":");
  86. var drive = registryPath.Substring(0, delimiterIndex);
  87. var subKey = registryPath.Substring(delimiterIndex + 2);
  88. Console.WriteLine(drive);
  89. Console.WriteLine(subKey);
  90. switch (drive)
  91. {
  92. case "HKU":
  93. return Registry.Users.OpenSubKey(subKey);
  94. case "HKCU":
  95. return Registry.CurrentUser.OpenSubKey(subKey);
  96. case "HKLM":
  97. return Registry.LocalMachine.OpenSubKey(subKey);
  98. default:
  99. throw new NotSupportedException($"Unknown registry drive {drive}");
  100. }
  101. }
  102. public static string FindEnvironmentVariableForUser(string variableName, string sid = null)
  103. {
  104. var normalizedName = variableName.ToLowerInvariant();
  105. RegistryKey sidKey = null;
  106. RegistryKey subKey = null;
  107. var mapped = new Dictionary<string, string>()
  108. {
  109. { "localappdata", "Local AppData"},
  110. { "local appdata", "Local AppData"},
  111. { "documents", "Personal" }
  112. };
  113. if (sid == null)
  114. {
  115. switch (normalizedName)
  116. {
  117. case "tmp":
  118. return Environment.GetEnvironmentVariable("TEMP");
  119. case "local appdata":
  120. return Environment.GetEnvironmentVariable("LOCALAPPDATA");
  121. case "onedrive":
  122. subKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\OneDrive\Accounts");
  123. if (subKey == null)
  124. return null;
  125. subKey = subKey.OpenSubKey("Personal");
  126. if (subKey == null)
  127. return null;
  128. return subKey.GetValue("UserFolder") as string;
  129. case "onedrivebusiness":
  130. subKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\OneDrive\Accounts");
  131. if (subKey == null)
  132. return null;
  133. subKey = subKey.OpenSubKey("Business1");
  134. if (subKey == null)
  135. return null;
  136. return subKey.GetValue("UserFolder") as string;
  137. case "documents":
  138. case "my music":
  139. case "my pictures":
  140. case "my video":
  141. case "personal":
  142. case "cache":
  143. case "cookies":
  144. case "fonts":
  145. case "history":
  146. case "favorites":
  147. case "desktop":
  148. case "programs":
  149. var localName = variableName;
  150. if (mapped.ContainsKey(normalizedName))
  151. localName = mapped[normalizedName];
  152. subKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders");
  153. if (subKey == null)
  154. return null;
  155. return subKey.GetValue(localName) as string;
  156. }
  157. return Environment.GetEnvironmentVariable(variableName);
  158. }
  159. switch (normalizedName)
  160. {
  161. case "userprofile":
  162. subKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\" + sid);
  163. if (subKey == null)
  164. return null;
  165. return subKey.GetValue("ProfileImagePath") as string;
  166. case "onedrive":
  167. sidKey = Registry.Users.OpenSubKey(sid);
  168. if (sidKey == null)
  169. return null;
  170. subKey = sidKey.OpenSubKey(@"SOFTWARE\Microsoft\OneDrive\Accounts");
  171. if (subKey == null)
  172. return null;
  173. subKey = subKey.OpenSubKey("Personal");
  174. if (subKey == null)
  175. return null;
  176. return subKey.GetValue("UserFolder") as string;
  177. case "onedrivebusiness":
  178. sidKey = Registry.Users.OpenSubKey(sid);
  179. if (sidKey == null)
  180. return null;
  181. subKey = sidKey.OpenSubKey(@"SOFTWARE\Microsoft\OneDrive\Accounts");
  182. if (subKey == null)
  183. return null;
  184. subKey = subKey.OpenSubKey("Business1");
  185. if (subKey == null)
  186. return null;
  187. return subKey.GetValue("UserFolder") as string;
  188. case "temp":
  189. case "tmp":
  190. case "local appdata":
  191. case "localappdata":
  192. case "appdata":
  193. case "documents":
  194. case "personal":
  195. case "cache":
  196. case "cookies":
  197. case "my music":
  198. case "my pictures":
  199. case "my video":
  200. case "favorites":
  201. case "fonts":
  202. case "history":
  203. case "desktop":
  204. case "programs":
  205. var localName = variableName;
  206. if (mapped.ContainsKey(normalizedName))
  207. localName = mapped[normalizedName];
  208. sidKey = Registry.Users.OpenSubKey(sid);
  209. if (sidKey == null)
  210. return null;
  211. subKey = sidKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders");
  212. if (subKey == null)
  213. return null;
  214. var value = subKey.GetValue(localName) as string;
  215. if (value != null && normalizedName == "temp" || normalizedName == "tmp")
  216. return Path.Combine(value , "Temp");
  217. return value;
  218. default:
  219. subKey = Registry.Users.OpenSubKey(sid);
  220. if (subKey != null)
  221. {
  222. subKey = subKey.OpenSubKey(@"Environment");
  223. if (subKey != null)
  224. {
  225. var keys = subKey.GetSubKeyNames();
  226. foreach (var key in keys)
  227. {
  228. if (normalizedName == key.ToLowerInvariant())
  229. {
  230. var path = subKey.GetValue(key) as string;
  231. if (path.Contains("%USERPROFILE%"))
  232. {
  233. subKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\" + sid);
  234. if (subKey != null)
  235. {
  236. var userProfile = subKey.GetValue("ProfileImagePath") as string;
  237. path = path.Replace("%USERPROFILE%", userProfile ?? "");
  238. }
  239. }
  240. if (path.Contains("%"))
  241. {
  242. //TODO handle other values;
  243. }
  244. return path;
  245. }
  246. }
  247. }
  248. }
  249. var globalVariables = Environment.GetEnvironmentVariables();
  250. foreach (string key in globalVariables.Keys)
  251. {
  252. if (key.ToLowerInvariant() == normalizedName)
  253. {
  254. return Environment.GetEnvironmentVariable(key);
  255. }
  256. }
  257. return null;
  258. }
  259. }
  260. }
  261. }