└── src ├── 303 ├── CSReg.cs ├── GetMoreProperties.cs ├── Modal.htm ├── UAC.png ├── WinSetView.htm ├── WinSetView.ico ├── WinSetView.ps1 └── seguiemj.eot └── 313 ├── CSReg.cs ├── CloseExplorerWindows.cs ├── GetMoreProperties.cs ├── Modal.htm ├── UAC.png ├── WinSetView.htm ├── WinSetView.ico ├── WinSetView.ps1 └── seguiemj.eot /src/303/CSReg.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Microsoft.Win32; 4 | using System.Linq; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace CSReg 9 | { 10 | internal class Program 11 | { 12 | // Global variable to control verbose output 13 | static bool isVerbose = false; 14 | 15 | static void Main(string[] args) 16 | { 17 | if (args.Length == 0) 18 | { 19 | Console.WriteLine("No arguments provided. Please specify an action."); 20 | return; 21 | } 22 | 23 | // Check if /verbose is passed as an argument 24 | isVerbose = args.Contains("/verbose"); 25 | 26 | // Filter out "/verbose" from the args so it doesn't interfere with command processing 27 | args = args.Where(arg => arg.ToLower() != "/verbose").ToArray(); 28 | 29 | string action = args[0].ToLower(); 30 | 31 | switch (action) 32 | { 33 | case "import": 34 | if (args.Length < 2) 35 | { 36 | Console.WriteLine("Usage: REG IMPORT FileName"); 37 | return; 38 | } 39 | ImportRegistryFile(args[1]); 40 | break; 41 | 42 | case "export": 43 | if (args.Length < 3) 44 | { 45 | Console.WriteLine("Usage: REG EXPORT KeyName FileName [/y]"); 46 | return; 47 | } 48 | ExportRegistryKey(args[1], args[2], args.Contains("/y")); 49 | break; 50 | 51 | case "delete": 52 | if (args.Length < 2) 53 | { 54 | Console.WriteLine("Usage: REG DELETE KeyName [/v ValueName | /ve | /va] [/f]"); 55 | return; 56 | } 57 | DeleteRegistryKeyOrValue(args); 58 | break; 59 | 60 | case "query": 61 | if (args.Length < 2) 62 | { 63 | Console.WriteLine("Usage: REG QUERY KeyName [/v [ValueName] | /ve]"); 64 | return; 65 | } 66 | QueryRegistryKeyOrValue(args); 67 | break; 68 | 69 | case "add": 70 | if (args.Length < 2) 71 | { 72 | Console.WriteLine("Usage: REG ADD KeyName [/v ValueName | /ve] [/t Type] [/d Data] [/f]"); 73 | return; 74 | } 75 | AddRegistryKeyOrValue(args); 76 | break; 77 | 78 | default: 79 | Console.WriteLine("Unsupported action. Use import, export, delete, query, or add."); 80 | break; 81 | } 82 | } 83 | 84 | // Helper method to display success messages 85 | static void DisplaySuccessMessage(string detailedMessage) 86 | { 87 | if (isVerbose) 88 | { 89 | Console.WriteLine(detailedMessage); 90 | } 91 | else 92 | { 93 | Console.WriteLine("The operation completed successfully."); 94 | } 95 | } 96 | 97 | // ADD function 98 | static void AddRegistryKeyOrValue(string[] args) 99 | { 100 | string keyPath = null; 101 | string valueName = ""; 102 | string valueData = ""; 103 | RegistryValueKind valueType = RegistryValueKind.String; // Default to REG_SZ 104 | bool force = false; 105 | 106 | // Start processing from args[1], where the key\subkey is located 107 | for (int i = 1; i < args.Length; i++) 108 | { 109 | switch (args[i].ToLower()) 110 | { 111 | case "/v": 112 | valueName = args[++i]; // Next argument is the value name 113 | break; 114 | case "/ve": 115 | valueName = ""; // Empty value name for default value 116 | break; 117 | case "/t": 118 | valueType = ParseValueType(args[++i]); // Next argument is the type 119 | break; 120 | case "/d": 121 | valueData = args[++i]; // Next argument is the data 122 | break; 123 | case "/f": 124 | force = true; // Force flag 125 | break; 126 | default: 127 | if (keyPath == null) keyPath = args[i]; // First positional argument is the keyPath 128 | break; 129 | } 130 | } 131 | 132 | if (keyPath == null) 133 | { 134 | throw new ArgumentException("Key path is required."); 135 | } 136 | 137 | try 138 | { 139 | keyPath = NormalizeKeyPath(keyPath); 140 | using (RegistryKey key = GetBaseRegistryKey(keyPath, writable: true, createSubKey: true)) 141 | { 142 | if (key == null) 143 | { 144 | throw new InvalidOperationException($"Failed to open or create registry key: {keyPath}"); 145 | } 146 | 147 | if (valueName != null) 148 | { 149 | object data = ConvertToRegistryValue(valueType, valueData); 150 | 151 | if (force || key.GetValue(valueName) == null) 152 | { 153 | key.SetValue(valueName, data, valueType); 154 | DisplaySuccessMessage($"Registry value added: {valueName} = {valueData}"); 155 | } 156 | else 157 | { 158 | Console.WriteLine($"Registry value already exists: {valueName}. Use /f to force overwrite."); 159 | } 160 | } 161 | else 162 | { 163 | DisplaySuccessMessage($"Key created: {keyPath}"); 164 | } 165 | } 166 | } 167 | catch (Exception ex) 168 | { 169 | Console.Error.WriteLine($"An error occurred: {ex.Message}"); 170 | } 171 | } 172 | 173 | // IMPORT function 174 | static void ImportRegistryFile(string filePath) 175 | { 176 | try 177 | { 178 | if (!File.Exists(filePath)) 179 | { 180 | Console.Error.WriteLine($"File not found: {filePath}"); 181 | return; 182 | } 183 | 184 | // Detect encoding based on the file content 185 | Encoding encoding = DetectFileEncoding(filePath); 186 | 187 | using (StreamReader reader = new StreamReader(filePath, encoding)) 188 | { 189 | string line; 190 | RegistryKey currentKey = null; 191 | string accumulatedLine = ""; // To accumulate lines with continuation characters 192 | 193 | while ((line = reader.ReadLine()) != null) 194 | { 195 | line = line.Trim(); 196 | 197 | // Skip empty, comment, and header lines 198 | if (string.IsNullOrWhiteSpace(line) || line.StartsWith(";") || line.StartsWith("Windows") || line.StartsWith("REGEDIT")) 199 | continue; 200 | 201 | // Handle line continuation (backslash at the end) 202 | if (line.EndsWith("\\")) 203 | { 204 | accumulatedLine += line.Substring(0, line.Length - 1).Trim(); 205 | continue; // Wait for the next line to continue processing 206 | } 207 | else 208 | { 209 | // Accumulate the last part of the line 210 | accumulatedLine += line.Trim(); 211 | } 212 | 213 | // Now process the complete accumulated line 214 | if (accumulatedLine.StartsWith("[") && accumulatedLine.EndsWith("]")) 215 | { 216 | // It's a key, so we process it as such 217 | string keyPath = accumulatedLine.Trim('[', ']'); 218 | currentKey?.Close(); 219 | 220 | currentKey = CreateOrOpenRegistryKey(keyPath); 221 | } 222 | else if (currentKey != null) 223 | { 224 | ParseAndSetRegistryValue(currentKey, accumulatedLine); 225 | } 226 | 227 | accumulatedLine = ""; 228 | } 229 | 230 | currentKey?.Close(); 231 | } 232 | 233 | DisplaySuccessMessage($"Successfully imported registry from file: {filePath}"); 234 | } 235 | catch (Exception ex) 236 | { 237 | Console.Error.WriteLine($"Error importing registry: {ex.Message}"); 238 | } 239 | } 240 | 241 | // Function to detect encoding by reading the byte order mark (BOM) or file content 242 | static Encoding DetectFileEncoding(string filePath) 243 | { 244 | using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read)) 245 | { 246 | if (file.Length >= 2) 247 | { 248 | byte[] bom = new byte[2]; 249 | file.Read(bom, 0, 2); 250 | 251 | // Check for UTF-16 LE BOM (FF FE) 252 | if (bom[0] == 0xFF && bom[1] == 0xFE) 253 | return Encoding.Unicode; 254 | 255 | // Check for UTF-16 BE BOM (FE FF) 256 | if (bom[0] == 0xFE && bom[1] == 0xFF) 257 | return Encoding.BigEndianUnicode; 258 | } 259 | 260 | // Default to ANSI (UTF-8 without BOM) 261 | return Encoding.Default; 262 | } 263 | } 264 | 265 | static RegistryKey CreateOrOpenRegistryKey(string keyPath) 266 | { 267 | try 268 | { 269 | keyPath = NormalizeKeyPath(keyPath); 270 | 271 | int firstSlashIndex = keyPath.IndexOf('\\'); 272 | if (firstSlashIndex == -1) 273 | { 274 | // No subkey exists, just return the base key 275 | return GetBaseRegistryKey(keyPath, writable: true, createSubKey: true); 276 | } 277 | 278 | string baseKeyName = keyPath.Substring(0, firstSlashIndex); 279 | string subKeyPath = keyPath.Substring(firstSlashIndex + 1); 280 | 281 | // Get the base registry key (e.g., HKEY_CURRENT_USER) 282 | RegistryKey baseKey = GetBaseRegistryKey(baseKeyName, writable: true, createSubKey: true); 283 | if (baseKey == null) 284 | { 285 | throw new InvalidOperationException($"Invalid base registry key: {baseKeyName}"); 286 | } 287 | 288 | // Create the subkey path if it doesn't exist 289 | return CreateSubKeyPath(baseKey, subKeyPath); 290 | } 291 | catch (Exception ex) 292 | { 293 | Console.Error.WriteLine($"Error creating or opening registry key '{keyPath}': {ex.Message}"); 294 | return null; 295 | } 296 | } 297 | 298 | static RegistryKey CreateSubKeyPath(RegistryKey baseKey, string subKeyPath) 299 | { 300 | try 301 | { 302 | // Recursively create or open each subkey in the path 303 | RegistryKey currentKey = baseKey.CreateSubKey(subKeyPath, true); 304 | if (currentKey == null) 305 | { 306 | throw new InvalidOperationException($"Failed to create or open registry subkey: {subKeyPath}"); 307 | } 308 | 309 | return currentKey; 310 | } 311 | catch (Exception ex) 312 | { 313 | Console.Error.WriteLine($"Error creating subkey path '{subKeyPath}': {ex.Message}"); 314 | return null; 315 | } 316 | } 317 | 318 | // EXPORT function 319 | static void ExportRegistryKey(string keyPath, string filePath, bool forceOverwrite) 320 | { 321 | keyPath = NormalizeKeyPath(keyPath); 322 | 323 | try 324 | { 325 | if (File.Exists(filePath) && !forceOverwrite) 326 | { 327 | Console.WriteLine($"File {filePath} already exists. Use /y to overwrite."); 328 | return; 329 | } 330 | 331 | using (RegistryKey key = GetBaseRegistryKey(keyPath)) 332 | { 333 | if (key == null) 334 | { 335 | Console.Error.WriteLine($"Registry key not found: {keyPath}"); 336 | return; 337 | } 338 | 339 | using (StreamWriter writer = new StreamWriter(filePath, false, System.Text.Encoding.Unicode)) 340 | { 341 | writer.WriteLine("Windows Registry Editor Version 5.00\r\n"); 342 | ExportKey(key, keyPath, writer); 343 | } 344 | DisplaySuccessMessage($"Registry exported to file: {filePath}"); 345 | } 346 | } 347 | catch (Exception ex) 348 | { 349 | Console.Error.WriteLine($"Error exporting registry: {ex.Message}"); 350 | } 351 | } 352 | 353 | static string NormalizeKeyPath(string keyPath) 354 | { 355 | // map abbreviations and full names to their full uppercase versions 356 | var keyMappings = new Dictionary(StringComparer.OrdinalIgnoreCase) 357 | { 358 | { "HKLM", "HKEY_LOCAL_MACHINE" }, 359 | { "HKEY_LOCAL_MACHINE", "HKEY_LOCAL_MACHINE" }, 360 | { "HKCU", "HKEY_CURRENT_USER" }, 361 | { "HKEY_CURRENT_USER", "HKEY_CURRENT_USER" }, 362 | { "HKCR", "HKEY_CLASSES_ROOT" }, 363 | { "HKEY_CLASSES_ROOT", "HKEY_CLASSES_ROOT" }, 364 | { "HKU", "HKEY_USERS" }, 365 | { "HKEY_USERS", "HKEY_USERS" }, 366 | { "HKCC", "HKEY_CURRENT_CONFIG" }, 367 | { "HKEY_CURRENT_CONFIG", "HKEY_CURRENT_CONFIG" } 368 | }; 369 | 370 | string[] pathParts = keyPath.Split(new char[] { '\\' }, 2); 371 | 372 | if (keyMappings.ContainsKey(pathParts[0])) 373 | { 374 | pathParts[0] = keyMappings[pathParts[0]]; 375 | } 376 | return pathParts.Length > 1 ? $"{pathParts[0]}\\{pathParts[1]}" : pathParts[0]; 377 | } 378 | 379 | static void ExportKey(RegistryKey key, string keyPath, StreamWriter writer) 380 | { 381 | writer.WriteLine($"[{keyPath}]"); 382 | foreach (string valueName in key.GetValueNames()) 383 | { 384 | object value = key.GetValue(valueName, null, RegistryValueOptions.DoNotExpandEnvironmentNames); 385 | RegistryValueKind kind = key.GetValueKind(valueName); 386 | writer.WriteLine(FormatRegistryValue(valueName, value, kind)); 387 | } 388 | writer.WriteLine(); 389 | 390 | foreach (string subkeyName in key.GetSubKeyNames()) 391 | { 392 | using (RegistryKey subKey = key.OpenSubKey(subkeyName)) 393 | { 394 | if (subKey != null) 395 | { 396 | ExportKey(subKey, $"{keyPath}\\{subkeyName}", writer); 397 | } 398 | } 399 | } 400 | } 401 | 402 | static string FormatRegistryValue(string name, object value, RegistryValueKind kind) 403 | { 404 | string formattedName = string.IsNullOrEmpty(name) ? "@" : $"\"{name.Replace("\\", "\\\\").Replace("\"", "\\\"")}\""; 405 | 406 | switch (kind) 407 | { 408 | case RegistryValueKind.String: 409 | return $"{formattedName}=\"{value.ToString().Replace("\\", "\\\\").Replace("\"", "\\\"")}\""; 410 | 411 | case RegistryValueKind.ExpandString: 412 | string hexExpandString = string.Join(",", BitConverter.ToString(Encoding.Unicode.GetBytes(value.ToString())).Split('-')); 413 | return $"{formattedName}=hex(2):{hexExpandString}"; 414 | 415 | case RegistryValueKind.DWord: 416 | return $"{formattedName}=dword:{((uint)(int)value).ToString("x8")}"; 417 | 418 | case RegistryValueKind.QWord: 419 | ulong qwordValue = Convert.ToUInt64(value); 420 | return $"{formattedName}=hex(b):{string.Join(",", BitConverter.GetBytes(qwordValue).Select(b => b.ToString("x2")))}"; 421 | 422 | case RegistryValueKind.Binary: 423 | return $"{formattedName}=hex:{BitConverter.ToString((byte[])value).Replace("-", ",")}"; 424 | 425 | case RegistryValueKind.MultiString: 426 | string[] multiStrings = (string[])value; 427 | var hexValues = multiStrings.SelectMany(s => Encoding.Unicode.GetBytes(s) 428 | .Select(b => b.ToString("x2")) 429 | .Concat(new[] { "00", "00" })) 430 | .ToList(); 431 | hexValues.AddRange(new[] { "00", "00" }); 432 | return $"{formattedName}=hex(7):{string.Join(",", hexValues)}"; 433 | 434 | case RegistryValueKind.None: 435 | byte[] noneData = value as byte[]; 436 | string hexNone = string.Join(",", noneData.Select(b => b.ToString("x2"))); 437 | return $"{formattedName}=hex(0):{hexNone}"; 438 | 439 | default: 440 | throw new NotSupportedException($"Unsupported registry value type: {kind}"); 441 | } 442 | } 443 | 444 | static void DeleteRegistryKeyOrValue(string[] args) 445 | { 446 | string keyPath = args[1]; 447 | keyPath = NormalizeKeyPath(keyPath); 448 | string valueName = null; 449 | bool deleteAllValues = false; 450 | bool force = args.Contains("/f"); 451 | 452 | if (args.Contains("/va")) 453 | { 454 | deleteAllValues = true; 455 | } 456 | else if (args.Contains("/ve")) 457 | { 458 | valueName = ""; // Default value 459 | } 460 | else if (args.Contains("/v")) 461 | { 462 | valueName = args[Array.IndexOf(args, "/v") + 1]; 463 | } 464 | 465 | try 466 | { 467 | string[] keyParts = keyPath.Split(new char[] { '\\' }, 2); 468 | string root = keyParts[0].ToUpper(); 469 | string subKey = keyParts.Length > 1 ? keyParts[1] : string.Empty; 470 | 471 | using (RegistryKey baseKey = GetBaseRegistryKey(root, writable: true)) 472 | { 473 | if (baseKey == null) 474 | { 475 | throw new ArgumentException($"Could not open the root hive: {root}"); 476 | } 477 | 478 | if (!string.IsNullOrEmpty(subKey)) 479 | { 480 | // Open subKey as writable to delete values within it 481 | using (RegistryKey targetKey = baseKey.OpenSubKey(subKey, writable: true)) 482 | { 483 | if (targetKey == null) 484 | { 485 | Console.Error.WriteLine($"ERROR: The system was unable to find the specified registry key or value."); 486 | return; 487 | } 488 | 489 | if (!force) 490 | { 491 | // Determine prompt based on whether deleting a key or a value 492 | if (deleteAllValues) 493 | { 494 | Console.Write($"Delete all values under the registry key {keyPath} (Yes/No)? "); 495 | } 496 | else if (valueName != null) 497 | { 498 | Console.Write($"Delete the registry value {valueName} (Yes/No)? "); 499 | } 500 | else 501 | { 502 | // Prompt for key deletion 503 | Console.Write($"Permanently delete the registry key {keyPath} (Yes/No)? "); 504 | } 505 | 506 | string response = Console.ReadLine(); 507 | if (string.IsNullOrEmpty(response) || !response.StartsWith("y", StringComparison.OrdinalIgnoreCase)) 508 | { 509 | Console.WriteLine("Operation cancelled."); 510 | return; 511 | } 512 | } 513 | 514 | if (deleteAllValues) 515 | { 516 | foreach (var name in targetKey.GetValueNames()) 517 | { 518 | targetKey.DeleteValue(name, throwOnMissingValue: false); 519 | } 520 | DisplaySuccessMessage($"All values deleted under key: {keyPath}"); 521 | } 522 | else if (valueName != null) 523 | { 524 | if (targetKey.GetValue(valueName) != null) 525 | { 526 | targetKey.DeleteValue(valueName); 527 | DisplaySuccessMessage($"Deleted value '{valueName}' under key: {keyPath}"); 528 | } 529 | else 530 | { 531 | Console.Error.WriteLine($"ERROR: The system was unable to find the specified registry key or value."); 532 | } 533 | } 534 | else 535 | { 536 | // Delete the entire subKey tree 537 | baseKey.DeleteSubKeyTree(subKey, throwOnMissingSubKey: false); 538 | DisplaySuccessMessage($"Deleted key: {keyPath}"); 539 | } 540 | } 541 | } 542 | else 543 | { 544 | Console.WriteLine("Cannot delete the root hive itself."); 545 | } 546 | } 547 | } 548 | catch (Exception ex) 549 | { 550 | Console.Error.WriteLine($"Error deleting registry key or value: {ex.Message}"); 551 | } 552 | } 553 | 554 | // QUERY function 555 | static void QueryRegistryKeyOrValue(string[] args) 556 | { 557 | string keyPath = args[1]; 558 | keyPath = NormalizeKeyPath(keyPath); 559 | string valueName = args.Contains("/v") ? args[Array.IndexOf(args, "/v") + 1] : null; 560 | bool queryDefaultValue = args.Contains("/ve"); 561 | bool isRecursive = args.Contains("/s"); // Check if /s is passed for recursive query 562 | bool hasValues = false; 563 | string myKey = @"HKEY_CURRENT_USER\Software\CSReg"; 564 | try { Registry.CurrentUser.OpenSubKey(@"Software\CSReg", true)?.DeleteValue("RetVal", false); } catch { } 565 | 566 | try 567 | { 568 | using (RegistryKey key = GetBaseRegistryKey(keyPath)) 569 | { 570 | if (key == null) 571 | { 572 | Console.Error.WriteLine($"ERROR: The system was unable to find the specified registry key or value."); 573 | return; 574 | } 575 | 576 | Console.WriteLine(); // Always print one blank line at the start 577 | 578 | if (valueName != null) // Query a specific value 579 | { 580 | object value = key.GetValue(valueName, null, RegistryValueOptions.DoNotExpandEnvironmentNames); 581 | if (value == null) 582 | { 583 | Console.Error.WriteLine($"ERROR: The system was unable to find the specified registry key or value."); 584 | } 585 | else 586 | { 587 | RegistryValueKind valueKind = key.GetValueKind(valueName); 588 | Console.WriteLine(keyPath); // Print the full registry key path 589 | Console.WriteLine($" {valueName} {FormatRegistryValueType(valueKind)} {FormatRegistryValueData(value, valueKind)}"); 590 | Console.WriteLine(); // print blank line 591 | Registry.SetValue(myKey, "RetVal", $"{value}", RegistryValueKind.String); 592 | } 593 | } 594 | else if (queryDefaultValue) // Query the default value 595 | { 596 | object defaultValue = key.GetValue(null, null, RegistryValueOptions.DoNotExpandEnvironmentNames); 597 | if (defaultValue != null) 598 | { 599 | RegistryValueKind defaultValueKind = key.GetValueKind(null); 600 | Console.WriteLine(keyPath); // Print the full registry key path 601 | Console.WriteLine($" (Default) {FormatRegistryValueType(defaultValueKind)} {FormatRegistryValueData(defaultValue, defaultValueKind)}"); 602 | Console.WriteLine(); // print blank line 603 | Registry.SetValue(myKey, "RetVal", $"{defaultValue}", RegistryValueKind.String); 604 | } 605 | else 606 | { 607 | Console.Error.WriteLine($"ERROR: The system was unable to find the specified registry key or value."); 608 | } 609 | } 610 | else 611 | { 612 | // If recursive, call recursive query method 613 | if (isRecursive) 614 | { 615 | QueryRegistryRecursively(key, keyPath); 616 | } 617 | else 618 | { 619 | // Query and print all values 620 | foreach (var name in key.GetValueNames()) 621 | { 622 | if (!hasValues) 623 | { 624 | Console.WriteLine(keyPath); // Print key path 625 | hasValues = true; 626 | } 627 | 628 | object value = key.GetValue(name, null, RegistryValueOptions.DoNotExpandEnvironmentNames); 629 | RegistryValueKind kind = key.GetValueKind(name); 630 | 631 | string valueNameToPrint = string.IsNullOrEmpty(name) ? "(Default)" : name; 632 | Console.WriteLine($" {valueNameToPrint} {FormatRegistryValueType(kind)} {FormatRegistryValueData(value, kind)}"); 633 | } 634 | 635 | // Print a blank line after values if any were found 636 | if (hasValues) Console.WriteLine(); 637 | 638 | // Query and print subkeys 639 | foreach (var subkeyName in key.GetSubKeyNames()) 640 | { 641 | Console.WriteLine($"{keyPath}\\{subkeyName}"); 642 | } 643 | } 644 | } 645 | } 646 | } 647 | catch (Exception ex) 648 | { 649 | Console.Error.WriteLine($"Error querying registry: {ex.Message}"); 650 | } 651 | } 652 | 653 | // Recursive query method for subkeys and values 654 | static void QueryRegistryRecursively(RegistryKey key, string keyPath) 655 | { 656 | bool hasValues = false; 657 | 658 | // Print values under the current key 659 | foreach (var name in key.GetValueNames()) 660 | { 661 | if (!hasValues) 662 | { 663 | Console.WriteLine(keyPath); // Print key path 664 | hasValues = true; 665 | } 666 | 667 | object value = key.GetValue(name, null, RegistryValueOptions.DoNotExpandEnvironmentNames); 668 | RegistryValueKind kind = key.GetValueKind(name); 669 | 670 | string valueNameToPrint = string.IsNullOrEmpty(name) ? "(Default)" : name; 671 | Console.WriteLine($" {valueNameToPrint} {FormatRegistryValueType(kind)} {FormatRegistryValueData(value, kind)}"); 672 | } 673 | 674 | // If values were printed, add a blank line after them 675 | if (hasValues) 676 | { 677 | Console.WriteLine(); 678 | } 679 | 680 | // Recurse into subkeys 681 | foreach (var subkeyName in key.GetSubKeyNames()) 682 | { 683 | string subkeyPath = $"{keyPath}\\{subkeyName}"; 684 | using (RegistryKey subkey = key.OpenSubKey(subkeyName)) 685 | { 686 | if (subkey != null) 687 | { 688 | QueryRegistryRecursively(subkey, subkeyPath); // Recurse into the subkey 689 | } 690 | } 691 | } 692 | } 693 | 694 | static string FormatRegistryValueType(RegistryValueKind kind) 695 | { 696 | switch (kind) 697 | { 698 | case RegistryValueKind.String: return "REG_SZ"; 699 | case RegistryValueKind.ExpandString: return "REG_EXPAND_SZ"; 700 | case RegistryValueKind.DWord: return "REG_DWORD"; 701 | case RegistryValueKind.QWord: return "REG_QWORD"; 702 | case RegistryValueKind.Binary: return "REG_BINARY"; 703 | case RegistryValueKind.MultiString: return "REG_MULTI_SZ"; 704 | case RegistryValueKind.None: return "REG_NONE"; 705 | default: return "UNKNOWN_TYPE"; 706 | } 707 | } 708 | 709 | static string FormatRegistryValueData(object value, RegistryValueKind kind) 710 | { 711 | switch (kind) 712 | { 713 | case RegistryValueKind.String: 714 | case RegistryValueKind.ExpandString: 715 | return value.ToString(); 716 | 717 | case RegistryValueKind.DWord: 718 | return "0x" + ((uint)(int)value).ToString("x"); 719 | 720 | case RegistryValueKind.QWord: 721 | return "0x" + ((ulong)(long)value).ToString("x"); 722 | 723 | case RegistryValueKind.Binary: 724 | return BitConverter.ToString((byte[])value).Replace("-", ""); 725 | 726 | case RegistryValueKind.MultiString: 727 | return string.Join("\\0", (string[])value); 728 | 729 | case RegistryValueKind.None: 730 | return ""; // No data for REG_NONE 731 | 732 | default: 733 | throw new NotSupportedException($"Unsupported registry value type: {kind}"); 734 | } 735 | } 736 | 737 | static RegistryKey GetBaseRegistryKey(string keyPath, bool writable = false, bool createSubKey = false) 738 | { 739 | string[] keyParts = keyPath.Split(new char[] { '\\' }, 2); // Split into root and subkey 740 | string root = keyParts[0].ToUpper(); 741 | string subKey = keyParts.Length > 1 ? keyParts[1] : string.Empty; // If there's no subkey, handle it as empty 742 | 743 | RegistryKey baseKey; 744 | 745 | switch (root) 746 | { 747 | case "HKEY_LOCAL_MACHINE": 748 | baseKey = Registry.LocalMachine; 749 | break; 750 | case "HKEY_CURRENT_USER": 751 | baseKey = Registry.CurrentUser; 752 | break; 753 | case "HKEY_CLASSES_ROOT": 754 | baseKey = Registry.ClassesRoot; 755 | break; 756 | case "HKEY_USERS": 757 | baseKey = Registry.Users; 758 | break; 759 | case "HKEY_CURRENT_CONFIG": 760 | baseKey = Registry.CurrentConfig; 761 | break; 762 | default: 763 | throw new NotSupportedException($"Unsupported root key: {root}"); 764 | } 765 | 766 | if (string.IsNullOrEmpty(subKey)) return baseKey; 767 | 768 | if (createSubKey) 769 | { 770 | return baseKey.CreateSubKey(subKey, writable); 771 | } 772 | else 773 | { 774 | return baseKey.OpenSubKey(subKey, writable); 775 | } 776 | } 777 | 778 | static RegistryValueKind ParseValueType(string type) 779 | { 780 | switch (type.ToUpper()) 781 | { 782 | case "REG_SZ": 783 | return RegistryValueKind.String; 784 | case "REG_MULTI_SZ": 785 | return RegistryValueKind.MultiString; 786 | case "REG_EXPAND_SZ": 787 | return RegistryValueKind.ExpandString; 788 | case "REG_DWORD": 789 | return RegistryValueKind.DWord; 790 | case "REG_QWORD": 791 | return RegistryValueKind.QWord; 792 | case "REG_BINARY": 793 | return RegistryValueKind.Binary; 794 | case "REG_NONE": 795 | return RegistryValueKind.None; 796 | default: 797 | throw new NotSupportedException($"Unsupported registry value type: {type}"); 798 | } 799 | } 800 | 801 | static object ConvertToRegistryValue(RegistryValueKind kind, string data) 802 | { 803 | switch (kind) 804 | { 805 | case RegistryValueKind.String: 806 | case RegistryValueKind.ExpandString: 807 | return data; 808 | 809 | case RegistryValueKind.DWord: 810 | return Convert.ToUInt32(data, 16); 811 | 812 | case RegistryValueKind.QWord: 813 | return Convert.ToUInt64(data, 16); 814 | 815 | case RegistryValueKind.MultiString: 816 | return data.Split(new[] { "\\0" }, StringSplitOptions.None); 817 | 818 | case RegistryValueKind.Binary: 819 | return Enumerable.Range(0, data.Length / 2).Select(x => Convert.ToByte(data.Substring(x * 2, 2), 16)).ToArray(); 820 | 821 | case RegistryValueKind.None: 822 | return Encoding.Unicode.GetBytes(data + '\0'); 823 | 824 | default: 825 | throw new NotSupportedException($"Unsupported registry value kind: {kind}"); 826 | } 827 | } 828 | 829 | static void ParseAndSetRegistryValue(RegistryKey key, string line) 830 | { 831 | string name; string valueData; bool empty; 832 | 833 | void GetNameAndData(string pattern) 834 | { 835 | string[] parts = line.Split(new string[] { pattern }, 2, StringSplitOptions.None); 836 | name = parts[0].Substring(1).Replace("\\\"", "\"").Replace("\\\\", "\\"); 837 | if (name == "@") name = null; 838 | valueData = parts[1].Substring(0, parts[1].Length); 839 | if (valueData.EndsWith("\"")) valueData = valueData.Substring(0, valueData.Length - 1); 840 | valueData = valueData.Replace("\\\"", "\"").Replace("\\\\", "\\"); 841 | empty = valueData.Length == 0; 842 | } 843 | 844 | void TrimThis(string pattern) 845 | { 846 | if (valueData.EndsWith(pattern)) valueData = valueData.Substring(0, valueData.Length - pattern.Length); 847 | if (valueData == "00,00") valueData = ""; 848 | empty = valueData.Length == 0; 849 | } 850 | 851 | if (line.StartsWith("@=")) 852 | { 853 | line = $"\"@\"{line.Substring(1)}"; 854 | } 855 | 856 | string regType = string.Empty; 857 | 858 | if (line.Contains("\"=\"")) regType = "REG_SZ"; 859 | else if (line.Contains("\"=dword:")) regType = "REG_DWORD"; 860 | else if (line.Contains("\"=hex(b):")) regType = "REG_QWORD"; 861 | else if (line.Contains("\"=hex:")) regType = "REG_BINARY"; 862 | else if (line.Contains("\"=hex(2):")) regType = "REG_EXPAND_SZ"; 863 | else if (line.Contains("\"=hex(7):")) regType = "REG_MULTI_SZ"; 864 | else if (line.Contains("\"=hex(0):")) regType = "REG_NONE"; 865 | 866 | switch (regType) 867 | { 868 | case "REG_SZ": 869 | GetNameAndData("\"=\""); 870 | key.SetValue(name, valueData, RegistryValueKind.String); 871 | break; 872 | 873 | case "REG_DWORD": 874 | GetNameAndData("\"=dword:"); 875 | uint dwordValue = Convert.ToUInt32(valueData, 16); 876 | key.SetValue(name, (int)dwordValue, RegistryValueKind.DWord); 877 | break; 878 | 879 | case "REG_QWORD": 880 | GetNameAndData("\"=hex(b):"); 881 | string[] bytePairs = valueData.Split(new[] { ',' }); 882 | ulong qwordValue = 0; 883 | for (int i = 0; i < bytePairs.Length; i++) 884 | { 885 | qwordValue |= ((ulong)Convert.ToByte(bytePairs[i], 16)) << (i * 8); 886 | } 887 | key.SetValue(name, qwordValue, RegistryValueKind.QWord); 888 | break; 889 | 890 | case "REG_BINARY": 891 | GetNameAndData("\"=hex:"); 892 | if (empty) 893 | { 894 | key.SetValue(name, new byte[0], RegistryValueKind.Binary); 895 | } 896 | else 897 | { 898 | byte[] binaryData = valueData.Split(',').Select(h => Convert.ToByte(h, 16)).ToArray(); 899 | key.SetValue(name, binaryData, RegistryValueKind.Binary); 900 | } 901 | break; 902 | 903 | case "REG_EXPAND_SZ": 904 | GetNameAndData("\"=hex(2):"); 905 | TrimThis(",00,00"); 906 | TrimThis(",00,00"); 907 | 908 | if (empty) 909 | { 910 | key.SetValue(name, string.Empty, RegistryValueKind.ExpandString); 911 | } 912 | else 913 | { 914 | byte[] binaryData = valueData.Split(',').Select(h => Convert.ToByte(h, 16)).ToArray(); 915 | string expandSzValue = Encoding.Unicode.GetString(binaryData); 916 | key.SetValue(name, expandSzValue, RegistryValueKind.ExpandString); 917 | } 918 | break; 919 | 920 | case "REG_MULTI_SZ": 921 | GetNameAndData("\"=hex(7):"); 922 | TrimThis(",00,00"); 923 | TrimThis(",00,00"); 924 | 925 | if (empty) 926 | { 927 | key.SetValue(name, new string[] { string.Empty }, RegistryValueKind.MultiString); 928 | } 929 | else 930 | { 931 | byte[] binaryData = valueData.Split(',').Select(h => Convert.ToByte(h, 16)).ToArray(); 932 | string multiSzValue = Encoding.Unicode.GetString(binaryData); 933 | string[] multiStringArray = multiSzValue.Split(new[] { '\0' }); 934 | key.SetValue(name, multiStringArray, RegistryValueKind.MultiString); 935 | } 936 | break; 937 | 938 | case "REG_NONE": 939 | GetNameAndData("\"=hex(0):"); 940 | if (empty) 941 | { 942 | key.SetValue(name, Encoding.Unicode.GetBytes("" + '\0'), RegistryValueKind.None); 943 | } 944 | else 945 | { 946 | byte[] binaryData = valueData.Split(',').Select(h => Convert.ToByte(h, 16)).ToArray(); 947 | key.SetValue(name, binaryData, RegistryValueKind.None); 948 | } 949 | break; 950 | 951 | default: 952 | throw new InvalidOperationException("Unknown registry value type."); 953 | } 954 | } 955 | } 956 | } 957 | -------------------------------------------------------------------------------- /src/303/GetMoreProperties.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.IO; 4 | using System.Collections.Generic; 5 | 6 | namespace GetMoreProperties 7 | { 8 | internal class Program 9 | { 10 | static void Main() 11 | { 12 | string tempPath = Path.GetTempPath(); 13 | string filePath = Path.Combine(tempPath, "Properties.tmp"); 14 | 15 | List matchingProperties = new List(); 16 | 17 | PSEnumeratePropertyDescriptions(PROPDESC_ENUMFILTER.PDEF_ALL, typeof(IPropertyDescriptionList).GUID, out var list); 18 | for (var i = 0; i < list.GetCount(); i++) 19 | { 20 | var pd = list.GetAt(i, typeof(IPropertyDescription).GUID); 21 | 22 | pd.GetDisplayName(out var p); 23 | if (p != IntPtr.Zero) 24 | { 25 | var viewable = pd.GetTypeFlags(PROPDESC_TYPE_FLAGS.PDTF_ISVIEWABLE) == PROPDESC_TYPE_FLAGS.PDTF_ISVIEWABLE; 26 | 27 | if (viewable) 28 | { 29 | string dname = Marshal.PtrToStringUni(p); 30 | Marshal.FreeCoTaskMem(p); 31 | 32 | pd.GetCanonicalName(out p); 33 | string cname = Marshal.PtrToStringUni(p); 34 | Marshal.FreeCoTaskMem(p); 35 | 36 | if (!cname.StartsWith("System") && !cname.StartsWith("Icaros")) 37 | { 38 | matchingProperties.Add($"{dname};.{cname}"); 39 | } 40 | } 41 | } 42 | } 43 | 44 | if (matchingProperties.Count > 0) 45 | { 46 | using (StreamWriter writer = new StreamWriter(filePath, false, System.Text.Encoding.Unicode)) 47 | { 48 | foreach (var property in matchingProperties) 49 | { 50 | writer.WriteLine(property); 51 | } 52 | } 53 | } 54 | } 55 | 56 | public struct PROPERTYKEY 57 | { 58 | public Guid fmtid; 59 | public int pid; 60 | } 61 | 62 | public enum PROPDESC_ENUMFILTER 63 | { 64 | PDEF_ALL = 0, 65 | PDEF_SYSTEM = 1, 66 | PDEF_NONSYSTEM = 2, 67 | PDEF_VIEWABLE = 3, 68 | PDEF_QUERYABLE = 4, 69 | PDEF_INFULLTEXTQUERY = 5, 70 | PDEF_COLUMN = 6, 71 | } 72 | 73 | [Flags] 74 | public enum PROPDESC_TYPE_FLAGS 75 | { 76 | PDTF_DEFAULT = 0, 77 | PDTF_MULTIPLEVALUES = 0x1, 78 | PDTF_ISINNATE = 0x2, 79 | PDTF_ISGROUP = 0x4, 80 | PDTF_CANGROUPBY = 0x8, 81 | PDTF_CANSTACKBY = 0x10, 82 | PDTF_ISTREEPROPERTY = 0x20, 83 | PDTF_INCLUDEINFULLTEXTQUERY = 0x40, 84 | PDTF_ISVIEWABLE = 0x80, 85 | PDTF_ISQUERYABLE = 0x100, 86 | PDTF_CANBEPURGED = 0x200, 87 | PDTF_SEARCHRAWVALUE = 0x400, 88 | PDTF_DONTCOERCEEMPTYSTRINGS = 0x800, 89 | PDTF_ALWAYSINSUPPLEMENTALSTORE = 0x1000, 90 | PDTF_ISSYSTEMPROPERTY = unchecked((int)0x80000000), 91 | PDTF_MASK_ALL = unchecked((int)0x80001fff), 92 | } 93 | 94 | [DllImport("propsys")] 95 | public static extern int PSEnumeratePropertyDescriptions(PROPDESC_ENUMFILTER filterOn, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IPropertyDescriptionList ppv); 96 | 97 | [ComImport, Guid("1F9FC1D0-C39B-4B26-817F-011967D3440E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 98 | public interface IPropertyDescriptionList 99 | { 100 | int GetCount(); 101 | [return: MarshalAs(UnmanagedType.Interface)] 102 | IPropertyDescription GetAt(int iElem, [MarshalAs(UnmanagedType.LPStruct)] Guid riid); 103 | } 104 | 105 | [ComImport, Guid("6F79D558-3E96-4549-A1D1-7D75D2288814"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 106 | public interface IPropertyDescription 107 | { 108 | PROPERTYKEY GetPropertyKey(); 109 | [PreserveSig] int GetCanonicalName(out IntPtr zPtr); 110 | int GetPropertyType(); 111 | [PreserveSig] int GetDisplayName(out IntPtr zPtr); 112 | [PreserveSig] int GetEditInvitation(out IntPtr zPtr); 113 | PROPDESC_TYPE_FLAGS GetTypeFlags(PROPDESC_TYPE_FLAGS mask); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/303/Modal.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 264 | 265 | 279 | 280 | 281 | 282 | 283 |
284 |
285 | 286 |
287 |
288 |
289 | 290 |
291 |
292 |
293 | 294 |
295 |
296 |
297 | 298 |
299 |
300 |
301 |
302 |
303 |
304 | 305 | 306 |
307 |
308 | 309 |
310 |
311 |
312 |
313 | 314 |
315 | 316 |
317 |
318 |
319 |

320 |
321 |


322 | 323 |
324 |
325 | 326 | 327 | -------------------------------------------------------------------------------- /src/303/UAC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesFerch/WinSetView/aee13bade40bed1db46cd640e2d6ea03524addd3/src/303/UAC.png -------------------------------------------------------------------------------- /src/303/WinSetView.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesFerch/WinSetView/aee13bade40bed1db46cd640e2d6ea03524addd3/src/303/WinSetView.ico -------------------------------------------------------------------------------- /src/303/WinSetView.ps1: -------------------------------------------------------------------------------- 1 | # WinSetView (Globally Set Explorer Folder Views) 2 | # Les Ferch, lesferch@gmail.com, 2021 - 2025 3 | # WinSetView.ps1 (Powershell script to set selected views) 4 | 5 | # One command line paramater is supported 6 | # Provide INI file name to set Explorer views 7 | # Provide REG file name to restore Explorer views from backup 8 | 9 | Param ( 10 | $File = '' 11 | ) 12 | 13 | Set-StrictMode -Off 14 | 15 | #$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" 16 | 17 | $Constrained = $false 18 | If ($ExecutionContext.SessionState.LanguageMode -eq "ConstrainedLanguage") {$Constrained = $true} 19 | 20 | If (-Not $Constrained) {$host.ui.RawUI.WindowTitle = "WinSetView"} 21 | 22 | # Read entire INI file into a dictionary object 23 | 24 | Function Get-IniContent ($FilePath) { 25 | $ini = @{} 26 | Switch -regex -file $FilePath { 27 | '^\[(.+)\]' # Section 28 | { 29 | $section = $matches[1] 30 | $ini[$section] = @{} 31 | } 32 | '(.+?)\s*=(.*)' # Key 33 | { 34 | $name,$value = $matches[1..2] 35 | $ini[$section][$name] = $value 36 | } 37 | } 38 | Return $ini 39 | } 40 | 41 | # Determine Windows version (also works for Windows Server) 42 | # Treat Windows 11 same as Windows 10 because they have same folder types and properties 43 | 44 | $Key = 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion' 45 | $Value = 'CurrentVersion' 46 | $NTVer = (Get-ItemProperty -Path $Key -Name $Value).$Value 47 | $Value = 'CurrentBuild' 48 | $CurBld = [Int](Get-ItemProperty -Path $Key -Name $Value).$Value 49 | $Value = 'UBR' 50 | $UBR = [Int](Get-ItemProperty -Path $Key -Name $Value -ErrorAction SilentlyContinue).$Value 51 | If ($NTVer -eq '6.1') {$WinVer = '7'} 52 | If (($NTVer -eq '6.2') -Or ($NTVer -eq '6.3')) {$WinVer = '8'} 53 | $Value = 'CurrentMajorVersionNumber' 54 | Try {[Int]$MajVer = (Get-ItemProperty -ErrorAction Stop -Path $Key -Name $Value).$Value} 55 | Catch {$MajVer = 0} 56 | If ($MajVer -ge 10) {$WinVer = '10'} 57 | 58 | If (($WinVer -ne '7') -And ($WinVer -ne '8') -And ($WinVer -ne '10')){ 59 | Write-Host `n'Windows 7, 8, 10 or higher is required.'`n 60 | Read-Host -Prompt 'Press Enter to continue' 61 | Exit 62 | } 63 | 64 | # Windows 7 includes Powershell 2 so this check should never fail 65 | 66 | If ($PSVersionTable.PSVersion.Major -lt 2) { 67 | Write-Host `n'Powershell 2 or higher is required.'`n 68 | Read-Host -Prompt 'Press Enter to continue' 69 | Exit 70 | } 71 | 72 | # Verify INI or REG file is supplied on the command line 73 | 74 | $FileExt = '' 75 | If ($File.Length -gt 4) {$FileExt = $File.SubString($File.Length-4)} 76 | 77 | If (-Not(($FileExt -eq '.ini') -Or ($FileExt -eq '.reg'))) { 78 | Write-Host `n'No INI or REG file supplied on command line.'`n 79 | Read-Host -Prompt 'Press Enter to continue' 80 | Exit 81 | } 82 | 83 | # Create PSScriptRoot variable if not exist (i.e. PowerShell 2) 84 | 85 | If (!$PSScriptRoot) {$PSScriptRoot = Split-Path $Script:MyInvocation.MyCommand.Path -Parent} 86 | 87 | # Make sure we can access the INI (or REG) file 88 | 89 | set-location $PSScriptRoot 90 | 91 | If (-Not(Test-Path -Path $File)) { 92 | Write-Host `n"File not found: $File"`n 93 | Read-Host -Prompt 'Press Enter to continue' 94 | Exit 95 | } 96 | 97 | If ($Constrained) { 98 | Write-Host `n"Settings on this computer put PowerShell in Constrained Language Mode." 99 | Write-Host "Some steps may take a bit longer to work around this restriction." 100 | } 101 | 102 | #Keys for use with Reg.exe (or CSReg.exe) command line 103 | $BagM = 'HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU' 104 | $Bags = 'HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags' 105 | $Shel = 'HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell' 106 | $Strm = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams' 107 | $Defs = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Defaults' 108 | $CUFT = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes' 109 | $LMFT = 'HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes' 110 | $Advn = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' 111 | $Clcm = 'HKCU\Software\Classes\CLSID\{86CA1AA0-34AA-4E8B-A509-50C905BAE2A2}' 112 | $Srch = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Search' 113 | $Srhl = 'HKCU\Software\Microsoft\Windows\CurrentVersion\SearchSettings' 114 | $Srdc = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Feeds\DSB' 115 | $BwgM = 'HKCU\Software\Microsoft\Windows\Shell\BagMRU' 116 | $Bwgs = 'HKCU\Software\Microsoft\Windows\Shell\Bags' 117 | $Desk = 'HKCU\Software\Microsoft\Windows\Shell\Bags\1\Desktop' 118 | $TBar = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Desktop' 119 | $Lets = 'HKCU\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement' 120 | $Remd = 'HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 121 | $E10A = 'HKCU\Software\Classes\CLSID\{2aa9162e-c906-4dd9-ad0b-3d24a8eef5a0}' 122 | $E10B = 'HKCU\Software\Classes\CLSID\{6480100b-5a83-4d1e-9f69-8ae5a88e9a33}' 123 | $ESTR = 'HKCU\Software\Classes\CLSID\{52205fd8-5dfb-447d-801a-d0b52f2e83e1}' 124 | $ESTC = 'HKCU\Software\Classes\CLSID\{52205fd8-5dfb-447d-801a-d0b52f2e83e1}\shell\OpenNewWindow\command' 125 | $CCMH = 'HKCU\Software\Classes\AllFileSystemObjects\shellex\ContextMenuHandlers\{C2FBB630-2971-11D1-A18C-00C04FD75D13}' 126 | $MCMH = 'HKCU\Software\Classes\AllFileSystemObjects\shellex\ContextMenuHandlers\{C2FBB631-2971-11D1-A18C-00C04FD75D13}' 127 | $UPol = 'HKCU\Software\Policies\Microsoft\Windows\Explorer' 128 | 129 | #Keys for use with PowerShell 130 | $ShPS = 'HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell' 131 | 132 | #Keys for building REG files 133 | $ImpR = '[HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\' 134 | 135 | #File paths 136 | $TempDir = "$env:TEMP" 137 | $AppData = "$env:APPDATA\WinSetView" 138 | $RegFile1 = "$TempDir\WinSetView1.reg" 139 | $RegFile2 = "$TempDir\WinSetView2.reg" 140 | $T1 = "$TempDir\WinSetView1.tmp" 141 | $T2 = "$TempDir\WinSetView2.tmp" 142 | $T3 = "$TempDir\WinSetView3.tmp" 143 | $T4 = "$TempDir\WinSetView4.tmp" 144 | $T5 = "$TempDir\WinSetView5.tmp" 145 | $T6 = "$TempDir\WinSetView6.tmp" 146 | $T7 = "$TempDir\WinSetView7.tmp" 147 | $ShellBak = "$TempDir\ShellBak.reg" 148 | $DeskBak = "$TempDir\DeskBak.reg" 149 | $TBarBak = "$TempDir\TBarBak.reg" 150 | $TimeStr = (get-date).ToString('yyyy-MM-dd-HHmm-ss') 151 | $RegExe = "$env:SystemRoot\System32\Reg.exe" 152 | $CmdExe = "$env:SystemRoot\System32\Cmd.exe" 153 | $IcaclsExe = "$env:SystemRoot\System32\Icacls.exe" 154 | $KillExe = "$env:SystemRoot\System32\TaskKill.exe" 155 | $UAppData = "$env:UserProfile\AppData" 156 | $CSRegExe = "$PSScriptRoot\AppParts\CSReg.exe" 157 | $ViveExe = "$PSScriptRoot\AppParts\ViVeTool.exe" 158 | 159 | 160 | function Get-ShortPath($Path) { 161 | return (-join (& $CmdExe /c "for %p in ("""$Path""") do @echo:%~sp")).Trim() 162 | } 163 | 164 | $CSRegExe = Get-ShortPath($CSRegExe) 165 | $ViveExe = Get-ShortPath($ViveExe) 166 | 167 | $C1=''; $C2=''; $C3=''; $C4=''; $C5='' 168 | 169 | $regCheck = & $RegExe query HKU 2>$Null 170 | if ($regCheck -eq $Null) { 171 | $RegExe = $CSRegExe 172 | If (-Not(Test-Path -Path $RegExe)) { 173 | Write-Host `n"File not found: $RegExe"`n 174 | Read-Host -Prompt 'Press Enter to continue' 175 | Exit 176 | } 177 | } 178 | 179 | If ($PSVersionTable.PSVersion.Major -lt 5) { 180 | $userSID = (Get-WmiObject -Class Win32_UserAccount -Filter "Name='$env:UserName'").SID 181 | } 182 | Else { 183 | try { $userSID = (Get-CimInstance -ErrorAction Stop -ClassName Win32_UserAccount -Filter "Name='$env:UserName'").SID } 184 | catch { 185 | $key = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry64) 186 | $subKey = $key.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI") 187 | $userSID = $subKey.GetValue("LastLoggedOnUserSID") 188 | } 189 | } 190 | 191 | $PolE = "HKU\$userSID\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" 192 | $PolEM = "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" 193 | $PolL = "HKU\$userSID\Software\Microsoft\Windows\CurrentVersion\Policies\ComDlg32\PlacesBar" 194 | 195 | # Use script folder if we have write access. Otherwise use AppData folder. 196 | 197 | $TestFile = "$PSScriptRoot\$TimeStr.txt" 198 | Try {[io.file]::OpenWrite($TestFile).close()} 199 | Catch {} 200 | If (Test-Path -Path $TestFile) { 201 | Remove-Item $TestFile 202 | $AppData = "$PSScriptRoot\AppData" 203 | } 204 | $BakFile = "$AppData\Backup\$TimeStr.reg" 205 | $Custom = "$AppData\WinSetViewCustom.reg" 206 | 207 | # Check for dark mode 208 | 209 | $Value = 'AppsUseLightTheme' 210 | $Key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize' 211 | $UseLight = (Get-ItemProperty -Path $Key -Name $Value -ErrorAction SilentlyContinue).$Value 212 | $DarkMode = $false 213 | If (($UseLight -is [int]) -And ($UseLight -eq 0)) { $DarkMode = $true } 214 | 215 | Function AdjustPrefix($String) { 216 | $String = $String.Replace("System.Icaros.","Icaros.") 217 | $String = $String.Replace("System..","") 218 | Return $String 219 | } 220 | 221 | Function ResetThumbCache { 222 | $ThumbCacheFiles = "$Env:LocalAppData\Microsoft\Windows\Explorer\thumbcache_*.db" 223 | & $IcaclsExe $ThumbCacheFiles /grant Everyone:F >$Null 2>$Null 224 | Remove-Item -Force -ErrorAction SilentlyContinue $ThumbCacheFiles 225 | } 226 | 227 | Function ResetStoreAppViews { 228 | $Exclude = 'WindowsTerminal','WebViewHost','MSTeams','Win32Bridge.Server','PhoneExperienceHost','ClipChamp','ClipChamp.CLI' 229 | $Pkgs = "$env:LocalAppData\Packages" 230 | If ($Constrained) {KillStoreAppsConstrained} Else {KillStoreApps} 231 | Get-ChildItem $Pkgs -Directory | ForEach-Object { 232 | Remove-Item -Force -ErrorAction SilentlyContinue "$Pkgs\$_\SystemAppData\Helium\UserClasses.dat" 233 | } 234 | } 235 | 236 | Function KillStoreApps { 237 | $Stor = 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store' 238 | $Key = Get-Item -Path $Stor 239 | ForEach ($ValueName in $($Key.GetValueNames())) { 240 | If ($ValueName -match 'c:\\program files\\windowsapps\\') { 241 | $FileName = Split-Path $ValueName -Leaf 242 | $FileNameBase = $FileName.ToLower().Replace(".exe","") 243 | If ($Exclude -NotContains $FileNameBase) { 244 | & $KillExe /im $FileName >$Null 2>$Null 245 | } 246 | } 247 | } 248 | } 249 | 250 | Function KillStoreAppsConstrained { 251 | $Stor = 'HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store' 252 | $registryValues = & $RegExe query $Stor 253 | $registryValues | ForEach-Object { 254 | $parts = $_.Trim() -split " " 255 | $valueName = $parts[0] 256 | if ($valueName -match 'c:\\program files\\windowsapps\\') { 257 | $FileName = Split-Path $valueName -Leaf 258 | $FileNameBase = $FileName.ToLower().Replace(".exe","") 259 | if ($Exclude -NotContains $FileNameBase) { 260 | & $KillExe /im $FileName >$Null 2>$Null 261 | } 262 | } 263 | } 264 | } 265 | 266 | Function RestartExplorer { 267 | & $RegExe Import $ShellBak 2>$Null 268 | & $RegExe Import $DeskBak 2>$Null 269 | & $RegExe Import $TBarBak 2>$Null 270 | & $RegExe Add $BwgM /v NodeSlots /d '02' /t REG_BINARY /f >$Null 271 | & $RegExe Add $BwgM /v NodeSlot /d 1 /t REG_DWORD /f >$Null 272 | If ($WinVer -ne '7') {ResetStoreAppViews} 273 | Stop-Process -Force -ErrorAction SilentlyContinue -ProcessName Explorer 274 | If ($ResetThumbs -eq 1) {ResetThumbCache} 275 | Explorer $PSScriptRoot 276 | Exit 277 | } 278 | 279 | Function DeleteUserKeys { 280 | & $RegExe Delete $BwgM /f 2>$Null 281 | & $RegExe Delete $Bwgs /f 2>$Null 282 | & $RegExe Delete $BagM /f 2>$Null 283 | & $RegExe Delete $Bags /f 2>$Null 284 | & $RegExe Delete $CUFT /f 2>$Null 285 | & $RegExe Delete $Defs /f 2>$Null 286 | } 287 | 288 | $Restore = ($FileExt -eq '.reg') 289 | 290 | If ($Restore) { 291 | Write-Host `n'Restore from backup...'`n 292 | } 293 | Else { 294 | 295 | $iniContent = Get-IniContent $File 296 | $Reset = $iniContent['Options']['Reset'] 297 | $Backup = $iniContent['Options']['Backup'] 298 | $Generic = [Int]$iniContent['Options']['Generic'] 299 | $NoFolderThumbs = [Int]$iniContent['Options']['NoFolderThumbs'] 300 | $UnhideAppData = [Int]$iniContent['Options']['UnhideAppData'] 301 | $UnhidePublicDesktop = [Int]$iniContent['Options']['UnhidePublicDesktop'] 302 | $ClassicSearch = [Int]$iniContent['Options']['ClassicSearch'] 303 | $HomeGrouping = [Int]$iniContent['Options']['HomeGrouping'] 304 | $LibraryGrouping = [Int]$iniContent['Options']['LibraryGrouping'] 305 | $SearchOnly = [Int]$iniContent['Options']['SearchOnly'] 306 | $SetVirtualFolders = [Int]$iniContent['Options']['SetVirtualFolders'] 307 | $ThisPCoption = [Int]$iniContent['Options']['ThisPCoption'] 308 | $ThisPCView = [Int]$iniContent['Options']['ThisPCView'] 309 | $ThisPCNG = [Int]$iniContent['Options']['ThisPCNG'] 310 | $ApplyViews = ($iniContent['Options']['ApplyViews'] -eq 1) 311 | $ApplyOptions = ($iniContent['Options']['ApplyOptions'] -eq 1) 312 | 313 | If ($Reset -eq 1) { 314 | Write-Host `n'Reset to Windows defaults...'`n 315 | } 316 | Else { 317 | Write-Host `n'Setting Explorer folder views...'`n 318 | } 319 | } 320 | 321 | Function RemoveTempFiles { 322 | Remove-Item $T1 2>$Null 323 | Remove-Item $T2 2>$Null 324 | Remove-Item $T3 2>$Null 325 | Remove-Item $T4 2>$Null 326 | Remove-Item $T5 2>$Null 327 | Remove-Item $T6 2>$Null 328 | Remove-Item $T7 2>$Null 329 | } 330 | 331 | $LogoExists = $false 332 | Try { $LogoExists = (Get-ItemProperty -Path $ShPS -ErrorAction SilentlyContinue).logo -eq 'none' } Catch {} 333 | 334 | RemoveTempFiles 335 | 336 | If ($Backup -eq 1) { 337 | If (!(Test-Path -Path "$AppData\Backup")) {Mkdir "$AppData\Backup" >$Null} 338 | & $RegExe Export $BagM $T1 /y 2>$Null 339 | & $RegExe Export $Bags $T2 /y 2>$Null 340 | & $RegExe Export $Strm $T3 /y 2>$Null 341 | & $RegExe Export $CUFT $T4 /y 2>$Null 342 | & $RegExe Export $BwgM $T5 /y 2>$Null 343 | & $RegExe Export $Bwgs $T6 /y 2>$Null 344 | & $RegExe Export $Advn $T7 /y 2>$Null 345 | & $CmdExe /c Copy $T1+$T2+$T3+$T4+$T5+$T6+$T7 $BakFile >$Null 2>$Null 346 | RemoveTempFiles 347 | } 348 | 349 | If ($ApplyViews -Or $Restore) { 350 | 351 | # Backup current Desktop view details 352 | & $RegExe Export $Desk $DeskBak /y 2>$Null 353 | & $RegExe Export $TBar $TBarBak /y 2>$Null 354 | 355 | & $RegExe Delete $Desk /f 2>$Null 356 | Remove-Item $ShellBak 2>$Null 357 | Remove-Item -Path "$ShPS\*" -Recurse 2>$Null 358 | If ($ApplyOptions) {Remove-ItemProperty -Path "$ShPS" -Name Logo 2>$Null} 359 | Remove-ItemProperty -Path "$ShPS" -Name FolderType 2>$Null 360 | Remove-ItemProperty -Path "$ShPS" -Name SniffedFolderType 2>$Null 361 | & $RegExe Export $Shel $ShellBak /y 2>$Null 362 | 363 | # Clear current Explorer view registry values 364 | 365 | DeleteUserKeys 366 | 367 | # Restore from backup, restart Explorer, exit 368 | 369 | If ($Restore) { 370 | & $RegExe Import $File 371 | RestartExplorer 372 | } 373 | } 374 | 375 | If ($ApplyOptions) { 376 | 377 | # Enable/disable show of file extensions 378 | 379 | $ShowExt = [Int]$iniContent['Options']['ShowExt'] 380 | & $RegExe Add $Advn /v HideFileExt /t REG_DWORD /d (1-$ShowExt) /f 381 | 382 | # Enable/disable compact view in Windows 11 383 | 384 | If ($CurBld -ge 21996) { 385 | $CompView = [Int]$iniContent['Options']['CompView'] 386 | & $RegExe Add $Advn /v UseCompactMode /t REG_DWORD /d ($CompView) /f 387 | } 388 | 389 | # Enable/disable show hidden files and folders 390 | 391 | $ShowHidden = [Int]$iniContent['Options']['ShowHidden'] 392 | & $RegExe Add $Advn /v Hidden /t REG_DWORD /d (2-$ShowHidden) /f 393 | 394 | # Enable/disable classic context menu in Windows 11 395 | 396 | If ($CurBld -ge 21996) { 397 | $ClassicContextMenu = [Int]$iniContent['Options']['ClassicContextMenu'] 398 | If ($ClassicContextMenu -eq 1) {& $RegExe Add "$Clcm\InprocServer32" /reg:64 /f 2>$Null} 399 | Else {& $RegExe Delete $Clcm /reg:64 /f 2>$Null} 400 | } 401 | 402 | # Enable/disable Copy and Move items in context menu 403 | 404 | $CopyMoveInMenu = [Int]$iniContent['Options']['CopyMoveInMenu'] 405 | If ($CopyMoveInMenu -eq 1) { 406 | & $RegExe Add $CCMH /reg:64 /f 2>$Null 407 | & $RegExe Add $MCMH /reg:64 /f 2>$Null 408 | } 409 | Else { 410 | & $RegExe Delete $CCMH /reg:64 /f 2>$Null 411 | & $RegExe Delete $MCMH /reg:64 /f 2>$Null 412 | } 413 | 414 | # Enable/disable Internet in Windows search 415 | 416 | $NoSearchInternet = [Int]$iniContent['Options']['NoSearchInternet'] 417 | $NoSearchHighlights = [Int]$iniContent['Options']['NoSearchHighlights'] 418 | If (($NoSearchInternet -eq 0) -or ($NoSearchHighlights -eq 0)) { 419 | & $RegExe Add $UPol /v DisableSearchBoxSuggestions /t REG_DWORD /d 0 /f 2>$Null 420 | } 421 | $NoSearchInternet = 1-$NoSearchInternet 422 | $NoSearchHighlights = 1-$NoSearchHighlights 423 | & $RegExe Add $Srch /v BingSearchEnabled /t REG_DWORD /d ($NoSearchInternet) /f 424 | & $RegExe Add $Srhl /v IsDynamicSearchBoxEnabled /t REG_DWORD /d ($NoSearchHighlights) /f 425 | & $RegExe Add $Srdc /v ShowDynamicContent /t REG_DWORD /d ($NoSearchHighlights) /f 426 | 427 | # Enable/disable folder thumbnails 428 | 429 | If ($NoFolderThumbs -eq 1) { 430 | $ResetThumbs = !$LogoExists 431 | & $RegExe Add $Shel /v Logo /d none /t REG_SZ /f 432 | } 433 | Else { 434 | & $RegExe Delete $Shel /v Logo /f 2>$Null 435 | $ResetThumbs = $LogoExists 436 | } 437 | 438 | # Unhide/hide AppData folder 439 | 440 | If ($UnhideAppData -eq 1) {& $CmdExe /c attrib -h "$UAppData"} 441 | Else {& $CmdExe /c attrib +h "$UAppData"} 442 | 443 | # Enable/disable classic search 444 | # Only applicable if "new" search is enabled 445 | # If "new" search is disabled, then you get classic search 446 | 447 | If (($CurBld -ge 18363) -And ($CurBld -lt 21996)) { 448 | $Key = "HKCU\Software\Classes\CLSID\{1d64637d-31e9-4b06-9124-e83fb178ac6e}" 449 | If ($ClassicSearch -eq 1) {& $RegExe add "$Key\TreatAs" /ve /t REG_SZ /d "{64bc32b5-4eec-4de7-972d-bd8bd0324537}" /reg:64 /f 2>$Null} 450 | Else {& $RegExe delete $Key /reg:64 /f 2>$Null} 451 | } 452 | 453 | # Enable/disable numerical sort order (UAC) 454 | 455 | $NoNumericalSort = $iniContent['Options']['NoNumericalSort'] 456 | 457 | $CurVal = & $RegExe Query $PolE /v NoStrCmpLogical 2>$Null 458 | If ($CurVal.Length -eq 4) {$CurVal = $CurVal[2][-1]} Else {$CurVal = 0} 459 | 460 | If ($CurVal -ne $NoNumericalSort) { 461 | $NoNumericalSort = [int]$NoNumericalSort 462 | $C1 = "$CSRegExe Add $PolE /v NoStrCmpLogical /t REG_DWORD /d $NoNumericalSort /f" 463 | } 464 | 465 | $CurVal = & $RegExe Query $PolEM /v NoStrCmpLogical 2>$Null 466 | If ($CurVal.Length -eq 4) { 467 | $CurVal = $CurVal[2][-1] 468 | If ($CurVal -ne $NoNumericalSort) { 469 | $NoNumericalSort = [int]$NoNumericalSort 470 | $C1 = "$C1;$CSRegExe Add $PolEM /v NoStrCmpLogical /t REG_DWORD /d $NoNumericalSort /f" 471 | } 472 | } 473 | 474 | # Enable/disable Windows 10 "new" search (UAC) 475 | 476 | If (($CurBld -ge 19045) -And ($CurBld -lt 21996) -And ($UBR -ge 3754)) { 477 | 478 | $Win10Search = $iniContent['Options']['Win10Search'] 479 | 480 | $CurVal = & $ViveExe /query /id:18755234 481 | If ($CurVal[4] -Match 'Enabled') {$CurVal = '1'} Else {$CurVal = '0'} 482 | 483 | If ($CurVal -ne $Win10Search) { 484 | $Action = '/enable' 485 | If ($Win10Search -eq '0') {$Action = '/disable'} 486 | $C2 = "$ViveExe $Action /id:18755234" 487 | } 488 | } 489 | 490 | # Enable/disable Windows 11 App SDK Explorer (UAC) 491 | 492 | If (($CurBld -eq 22621) -And ($UBR -ge 3007) -And ($UBR -lt 3085)) { 493 | 494 | $Win11Explorer = $iniContent['Options']['Win11Explorer'] 495 | 496 | $CurVal = & $ViveExe /query /id:40729001 497 | If ($CurVal[4] -Match 'Disabled') {$CurVal = '1'} Else {$CurVal = '0'} 498 | 499 | If ($CurVal -ne $Win11Explorer) { 500 | $Action = '/enable' 501 | If ($Win11Explorer -eq '1') {$Action = '/disable'} 502 | $C3 = "$ViveExe $Action /id:40729001" 503 | } 504 | } 505 | 506 | # Enable/disable Windows 10 Explorer on Windows 11 507 | 508 | If ($CurBld -ge 21996) { 509 | 510 | $Win10Explorer = $iniContent['Options']['Win10Explorer'] 511 | 512 | If ($Win10Explorer -eq '1') { 513 | & $RegExe Add $E10A /ve /t REG_SZ /d "CLSID_ItemsViewAdapter" /reg:64 /f 514 | & $RegExe Add "$E10A\InProcServer32" /ve /t REG_SZ /d "C:\Windows\System32\Windows.UI.FileExplorer.dll_" /reg:64 /f 515 | & $RegExe Add "$E10A\InProcServer32" /v "ThreadingModel" /t REG_SZ /d "Apartment" /reg:64 /f 516 | & $RegExe Add $E10B /ve /t REG_SZ /d "File Explorer Xaml Island View Adapter" /reg:64 /f 517 | & $RegExe Add "$E10B\InProcServer32" /ve /t REG_SZ /d "C:\Windows\System32\Windows.UI.FileExplorer.dll_" /reg:64 /f 518 | & $RegExe Add "$E10B\InProcServer32" /v "ThreadingModel" /t REG_SZ /d "Apartment" /reg:64 /f 519 | 520 | # This binary value is required for the old Explorer to remember its window size and position 521 | & $RegExe Add "HKCU\Software\Microsoft\Internet Explorer\Toolbar\ShellBrowser" /f /v ITBar7Layout /t REG_BINARY /d 13000000000000000000000020000000100001000000000001000000010700005e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 522 | } 523 | Else { 524 | & $RegExe Delete $E10A /reg:64 /f 2>$Null 525 | & $RegExe Delete $E10B /reg:64 /f 2>$Null 526 | } 527 | } 528 | 529 | # Apply/remove Legacy Dialog Fix (UAC) 530 | 531 | If ($CurBld -ge 18363) { 532 | 533 | Try { 534 | $CurVal = & $RegExe Query $PolL /v Place1 2>$Null 535 | If ($CurVal.Length -eq 4) {$CurVal = '1'} Else {$CurVal = '0'} 536 | } 537 | Catch { 538 | $CurVal = '0' 539 | } 540 | 541 | $LegacyDialogFix = $iniContent['Options']['LegacyDialogFix'] 542 | 543 | $DesktopPlace = 'shell:::{3936E9E4-D92C-4EEE-A85A-BC16D5EA0819}' 544 | If (($CurBld -ge 22621) -And ($UBR -ge 3007)) { 545 | $DesktopPlace = 'shell:::{F874310E-B6B7-47DC-BC84-B9E6B38F5903}' 546 | } 547 | 548 | If ($CurVal -ne $LegacyDialogFix) { 549 | If ($LegacyDialogFix -eq '1') { 550 | $A = "$CSRegExe Add $PolL /v Place0 /t REG_SZ /d '$DesktopPlace' /f" 551 | $B = "$CSRegExe Add $PolL /v Place1 /t REG_SZ /d 'shell:ThisPCDesktopFolder' /f" 552 | $C = "$CSRegExe Add $PolL /v Place2 /t REG_SZ /d 'shell:Libraries' /f" 553 | $D = "$CSRegExe Add $PolL /v Place3 /t REG_SZ /d 'shell:MyComputerFolder' /f" 554 | $E = "$CSRegExe Add $PolL /v Place4 /t REG_SZ /d 'shell:NetworkPlacesFolder' /f" 555 | $C4 = "$A;$B;$C;$D;$E" 556 | } 557 | Else { 558 | $C4 = "$CSRegExe Delete $PolL /f" 2>$Null 559 | } 560 | } 561 | } 562 | 563 | # Unhide/hide Public Desktop folder 564 | 565 | $folderPath = "C:\Users\Public\Desktop" 566 | $folder = Get-Item -Path $folderPath -Force 567 | if ($folder.Attributes -band [System.IO.FileAttributes]::Hidden) { 568 | If ($UnhidePublicDesktop -eq 1) {$C5 = "$CmdExe /c attrib -h $folderPath"} 569 | } else { 570 | If ($UnhidePublicDesktop -eq 0) {$C5 = "$CmdExe /c attrib +h $folderPath"} 571 | } 572 | 573 | # Execute commands that require UAC elevation 574 | 575 | $Cmd = "$C1$C2$C3$C4$C5" 576 | If ($Cmd -ne '') { 577 | $Cmd = "$C1;$C2;$C3;$C4;$C5" 578 | Try { 579 | Start-Process -WindowStyle Hidden -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command $Cmd" -Verb RunAs 2>$Null 580 | } 581 | Catch { 582 | } 583 | } 584 | 585 | # Enable/disable "Let's finish setting up", "Welcome experience", and "Tips and tricks" 586 | 587 | $NoSuggestions = [Int]$iniContent['Options']['NoSuggestions'] 588 | $NoSuggestions = 1-$NoSuggestions 589 | & $RegExe Add $Lets /v ScoobeSystemSettingEnabled /t REG_DWORD /d ($NoSuggestions) /f 590 | & $RegExe Add $remd /v SubscribedContent-310093Enabled /t REG_DWORD /d ($NoSuggestions) /f 591 | & $RegExe Add $remd /v SubscribedContent-338389Enabled /t REG_DWORD /d ($NoSuggestions) /f 592 | 593 | # Set Explorer Start Folder 594 | 595 | & $RegExe Delete $ESTR /reg:64 /f 2>$Null 596 | $ExplorerStart = [Int]$iniContent['Options']['ExplorerStart'] 597 | If ($ExplorerStart -eq 1) { 598 | $ExplorerStartOption = [Int]$iniContent['Options']['ExplorerStartOption'] 599 | If ($ExplorerStartOption -eq 4) { 600 | $ExplorerStartPath = 'explorer ' + $iniContent['Options']['ExplorerStartPath'] 601 | $ExplorerStartPath = $ExplorerStartPath -Replace '\\$', '\\' 602 | & $RegExe Add $ESTC /ve /t REG_SZ /d $ExplorerStartPath /reg:64 /f 603 | & $RegExe Add $ESTC /v DelegateExecute /t REG_SZ /reg:64 /f 604 | } 605 | Else { 606 | & $RegExe Add $Advn /v LaunchTo /t REG_DWORD /d ($ExplorerStartOption) /f 607 | } 608 | } 609 | } 610 | 611 | # If reset, restart Explorer and exit 612 | 613 | If ($Reset -eq 1) { 614 | & $RegExe Delete $Strm /f 2>$Null 615 | RestartExplorer 616 | } 617 | 618 | # Function to help Set up views for This PC 619 | 620 | Function SetBagValues ($Key) { 621 | & $RegExe Add $Key /v FFlags /d 0x41200001 /t REG_DWORD /f >$Null 622 | & $RegExe Add $Key /v LogicalViewMode /d $LVMode /t REG_DWORD /f >$Null 623 | & $RegExe Add $Key /v Mode /d $Mode /t REG_DWORD /f >$Null 624 | $Group = 1-$ThisPCNG 625 | & $RegExe Add $Key /v GroupView /d $Group /t REG_DWORD /f >$Null 626 | If ($LVMode -eq 3) {& $RegExe Add $Key /v IconSize /d $IconSize /t REG_DWORD /f >$Null} 627 | } 628 | 629 | # Set view values based on selection index 630 | 631 | Function SetViewValues($Index) { 632 | If ($Index -eq 1) {$Script:LVMode = 1; $Script:Mode = 4; $Script:IconSize = 16} 633 | If ($Index -eq 2) {$Script:LVMode = 4; $Script:Mode = 3; $Script:IconSize = 16} 634 | If ($Index -eq 3) {$Script:LVMode = 2; $Script:Mode = 6; $Script:IconSize = 48} 635 | If ($Index -eq 4) {$Script:LVMode = 5; $Script:Mode = 8; $Script:IconSize = 32} 636 | If ($Index -eq 5) {$Script:LVMode = 3; $Script:Mode = 1; $Script:IconSize = 16} 637 | If ($Index -eq 6) {$Script:LVMode = 3; $Script:Mode = 1; $Script:IconSize = 48} 638 | If ($Index -eq 7) {$Script:LVMode = 3; $Script:Mode = 1; $Script:IconSize = 96} 639 | If ($Index -eq 8) {$Script:LVMode = 3; $Script:Mode = 1; $Script:IconSize = 256} 640 | } 641 | 642 | Function BuildRegData($Key) { 643 | $Script:RegData += $Script:ImpR + "$Key\$GUID]`r`n" 644 | $Script:RegData += '@="' + $Script:FT + '"' + "`r`n" 645 | $Script:RegData += '"Mode"=dword:' + $Script:Mode + "`r`n" 646 | If ($Key -eq 'Shell') { 647 | $Script:RegData += '"FFlags"=dword:43000001' + "`r`n" 648 | Return 649 | } 650 | $Script:RegData += '"LogicalViewMode"=dword:' + $Script:LVMode + "`r`n" 651 | If ($Script:LVMode -eq 3) {$Script:RegData += '"IconSize"=dword:' + '{0:x}' -f $Script:IconSize + "`r`n"} 652 | $Group = 1-$FileDialogNG 653 | $Script:RegData += '"GroupView"=dword:' + $Group + "`r`n" 654 | } 655 | 656 | If ($ApplyViews) { 657 | 658 | # Enable/Disable full row select (requires legacy spacing) 659 | 660 | $LegacySpacing = [Int]$iniContent['Options']['LegacySpacing'] 661 | $NoFullRowSelect = 0 662 | If ($LegacySpacing -eq 1) { 663 | $NoFullRowSelect = [Int]$iniContent['Options']['NoFullRowSelect'] 664 | If ($DarkMode) { 665 | # set text color here 666 | } 667 | } 668 | 669 | & $RegExe Add $Advn /v FullRowSelect /t REG_DWORD /d (1-$NoFullRowSelect) /f 670 | 671 | # The FolderTypes key does not include entries for This PC 672 | # This PC does not have a unique GUID so we'll set it's view via a Bags entry: 673 | 674 | If ($ThisPCoption -ne 0) { 675 | & $RegExe Add $BagM /v NodeSlots /d '02' /t REG_BINARY /f 676 | & $RegExe Add $BagM /v MRUListEx /d '00000000ffffffff' /t REG_BINARY /f >$Null 677 | & $RegExe Add $BagM /v '0' /d '14001F50E04FD020EA3A6910A2D808002B30309D0000' /t REG_BINARY /f >$Null 678 | & $RegExe Add "$BagM\0" /v NodeSlot /d 1 /t REG_DWORD /f >$Null 679 | $CustomIconSize = $iniContent['Generic']['IconSize'] 680 | SetViewValues($ThisPCView) 681 | If ($CustomIconSize -ne '') {$IconSize = $CustomIconSize} 682 | $GUID = '{5C4F28B5-F869-4E84-8E60-F11DB97C5CC7}' 683 | SetBagValues("$Bags\1\ComDlg\$GUID") 684 | SetBagValues("$Bags\1\Shell\$GUID") 685 | } 686 | 687 | If ($Generic -eq 1) {& $RegExe Add $Shel /v FolderType /d Generic /t REG_SZ /f} 688 | 689 | If ($SetVirtualFolders -eq 1) { 690 | $GUID = $iniContent['Generic']['GUID'] 691 | $GroupBy = $iniContent['Generic']['GroupBy'] 692 | $CustomIconSize = $iniContent['Generic']['IconSize'] 693 | SetViewValues([Int]$iniContent['Generic']['View']) 694 | If ($CustomIconSize -ne '') {$IconSize = $CustomIconSize} 695 | & $RegExe Add "$Bags\AllFolders\Shell\$GUID" /v FFlags /d '0x41200001' /t REG_DWORD /f 696 | & $RegExe Add "$Bags\AllFolders\Shell\$GUID" /v Mode /d "$Mode" /t REG_DWORD /f 697 | & $RegExe Add "$Bags\AllFolders\Shell\$GUID" /v LogicalViewMode /d "$LVMode" /t REG_DWORD /f 698 | If ($LVMode -eq 3) {& $RegExe Add "$Bags\AllFolders\Shell\$GUID" /v IconSize /d "$IconSize" /t REG_DWORD /f} 699 | If ($GroupBy -eq '') {& $RegExe Add "$Bags\AllFolders\Shell\$GUID" /v GroupView /d 0 /t REG_DWORD /f} 700 | } 701 | 702 | # Set Explorer folder view defaults: 703 | # 1) Export HKLM FolderTypes key 704 | # 2) Import FolderTypes key to HKCU 705 | # 2) Update HKCU FolderTypes default settings 706 | # 4) Restart Explorer 707 | # Note: Explorer will use HKCU key instead of HKLM key automatically 708 | 709 | # Copy FolderType key from HKLM to HKCU by exporting and importing 710 | 711 | & $RegExe Export $LMFT $RegFile1 /y 712 | $Data = Get-Content $RegFile1 713 | $Data = $Data -Replace 'HKEY_LOCAL_MACHINE','HKEY_CURRENT_USER' 714 | Out-File -InputObject $Data -encoding Unicode -filepath $RegFile1 715 | & $RegExe Import $RegFile1 /reg:64 716 | 717 | $FolderTypes = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes' 718 | 719 | # Create lookup table for path type properties so these can be excluded from 720 | # non-search views if the search-only option is enabled 721 | 722 | $PathItems = @{ 723 | 'ItemFolderPathDisplay' = '' 724 | 'ItemFolderPathDisplayNarrow' = '' 725 | 'ItemPathDisplay' = '' 726 | 'ItemFolderNameDisplay' = '' 727 | } 728 | 729 | $RegData = '' 730 | 731 | Get-ChildItem $FolderTypes | Get-ItemProperty | ForEach { 732 | 733 | $FT = $_.CanonicalName 734 | If ($iniContent.ContainsKey($FT)) { 735 | $Include = [Int]$iniContent[$FT]['Include'] 736 | 737 | If ($Include -eq 1) { 738 | 739 | $FileDialogOption = [Int]$iniContent[$FT]['FileDialogOption'] 740 | $FileDialogView = [Int]$iniContent[$FT]['FileDialogView'] 741 | $FileDialogNG = [Int]$iniContent[$FT]['FileDialogNG'] 742 | 743 | $GUID = $iniContent[$FT]['GUID'] 744 | 745 | $View = $iniContent[$FT]['View'] 746 | If ($FileDialogOption -ne 1) {$FileDialogView = $View} 747 | 748 | If (($FileDialogOption -eq 1 -And $FT -ne 'Global') -Or ($SetVirtualFolders -eq 1 -And $GUID -eq '{5C4F28B5-F869-4E84-8E60-F11DB97C5CC7}')) { 749 | SetViewValues($FileDialogView) 750 | BuildRegData('ComDlg') 751 | BuildRegData('ComDlgLegacy') 752 | } 753 | 754 | SetViewValues($View) 755 | 756 | If ($LegacySpacing -eq 1) { 757 | BuildRegData('Shell') 758 | } 759 | 760 | $GroupBy = $iniContent[$FT]['GroupBy'] 761 | $GroupByOrder = $iniContent[$FT]['GroupByOrder'] 762 | If (($FT -eq 'HomeFolder') -And ($HomeGrouping -eq 0)) { 763 | $GroupBy = 'Home.Grouping' 764 | $GroupByOrder = '+' 765 | } 766 | If (($FT.IndexOf('Library') -gt 0) -And ($LibraryGrouping -eq 0)) { 767 | $GroupBy = 'ItemSearchLocation' 768 | $GroupByOrder = '+' 769 | } 770 | If ($GroupBy -ne '') {$GroupBy = "System.$GroupBy"} 771 | $GroupBy = AdjustPrefix($GroupBy) 772 | If ($GroupByOrder -eq '+') {$GroupByOrder = 1} Else {$GroupByOrder = 0} 773 | 774 | #Code added June 2023 to disable Sort 4 775 | $SortBy = $iniContent[$FT]['SortBy'] 776 | If ($SortBy.Split(';').Count -eq 4) { 777 | $SortBy = $SortBy.SubString(0,$SortBy.LastIndexOf(';')) 778 | } 779 | $SortBy = 'prop:' + $SortBy 780 | $SortBy = $SortBy -Replace '\+','+System.' 781 | $SortBy = $SortBy -Replace '-','-System.' 782 | $SortBy = AdjustPrefix($SortBy) 783 | 784 | $CustomIconSize = $iniContent[$FT]['IconSize'] 785 | If ($CustomIconSize -ne '') {$IconSize = $CustomIconSize} 786 | $INIColumnList = $iniContent[$FT]['ColumnList'] 787 | $ArrColumnList = $INIColumnList.Split(';') 788 | $ColumnList = 'prop:' 789 | 790 | For($i=0; $i -lt $ArrColumnList.Count; $i++) { 791 | $ArrColumnListItem = $ArrColumnList[$i].Split(',') 792 | $Property = $ArrColumnListItem[2] 793 | If (($FT -Match 'Search') -Or (-Not ((($SearchOnly -eq 1) -And ($PathItems.ContainsKey($Property))) -Or ($Property -eq 'Search.Rank')))) { 794 | $Show = $ArrColumnListItem[0] 795 | $Width = ''; If ($ArrColumnListItem[1] -ne '') {$Width = '(' + $ArrColumnListItem[1] + ')'} 796 | $Property = 'System.' + $ArrColumnListItem[2] 797 | $Property = AdjustPrefix($Property) 798 | $ColumnList = "$ColumnList$Show$Width$Property;" 799 | } 800 | } 801 | $ColumnList = $ColumnList.Trim(';') 802 | $Key = $_.PSPath 803 | $Key = "$Key\TopViews" 804 | If (Test-Path -Path $Key) { 805 | Get-ChildItem $Key | Get-ItemProperty | ForEach { 806 | $GUID = $_.PSChildName 807 | $ChildKey = $Key + '\' + $GUID 808 | Set-ItemProperty -Path $ChildKey -Name 'LogicalViewMode' -Value $LVMode 809 | Set-ItemProperty -Path $ChildKey -Name 'IconSize' -Value $IconSize 810 | Set-ItemProperty -Path $ChildKey -Name 'GroupBy' -Value $GroupBy 811 | Set-ItemProperty -Path $ChildKey -Name 'GroupAscending' -Value $GroupByOrder 812 | Set-ItemProperty -Path $ChildKey -Name 'SortByList' -Value $SortBy 813 | Set-ItemProperty -Path $ChildKey -Name 'ColumnList' -Value $ColumnList 814 | } 815 | } 816 | } 817 | } 818 | } 819 | 820 | # Export results for use with comparison tools such as WinMerge 821 | 822 | & $RegExe Export $CUFT $RegFile2 /y 823 | 824 | # Import Reg data to force dialog views 825 | # This is MUCH faster than creating the keys using PowerShell 826 | 827 | If ($RegData -ne '') { 828 | $RegData = "Windows Registry Editor Version 5.00`r`n`r`n" + $RegData 829 | Out-File -InputObject $RegData -filepath $T1 830 | & $RegExe Import $T1 831 | } 832 | } 833 | 834 | # Import Reg data for any custom settings 835 | 836 | If (Test-Path -Path $Custom) {& $RegExe Import $Custom /reg:64} 837 | 838 | RestartExplorer -------------------------------------------------------------------------------- /src/303/seguiemj.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesFerch/WinSetView/aee13bade40bed1db46cd640e2d6ea03524addd3/src/303/seguiemj.eot -------------------------------------------------------------------------------- /src/313/CSReg.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Microsoft.Win32; 4 | using System.Linq; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace CSReg 9 | { 10 | internal class Program 11 | { 12 | // Global variable to control verbose output 13 | static bool isVerbose = false; 14 | 15 | static void Main(string[] args) 16 | { 17 | if (args.Length == 0) 18 | { 19 | Console.WriteLine("No arguments provided. Please specify an action."); 20 | return; 21 | } 22 | 23 | // Check if /verbose is passed as an argument 24 | isVerbose = args.Contains("/verbose"); 25 | 26 | // Filter out "/verbose" from the args so it doesn't interfere with command processing 27 | args = args.Where(arg => arg.ToLower() != "/verbose").ToArray(); 28 | 29 | string action = args[0].ToLower(); 30 | 31 | switch (action) 32 | { 33 | case "import": 34 | if (args.Length < 2) 35 | { 36 | Console.WriteLine("Usage: REG IMPORT FileName"); 37 | return; 38 | } 39 | ImportRegistryFile(args[1]); 40 | break; 41 | 42 | case "export": 43 | if (args.Length < 3) 44 | { 45 | Console.WriteLine("Usage: REG EXPORT KeyName FileName [/y]"); 46 | return; 47 | } 48 | ExportRegistryKey(args[1], args[2], args.Contains("/y")); 49 | break; 50 | 51 | case "delete": 52 | if (args.Length < 2) 53 | { 54 | Console.WriteLine("Usage: REG DELETE KeyName [/v ValueName | /ve | /va] [/f]"); 55 | return; 56 | } 57 | DeleteRegistryKeyOrValue(args); 58 | break; 59 | 60 | case "query": 61 | if (args.Length < 2) 62 | { 63 | Console.WriteLine("Usage: REG QUERY KeyName [/v [ValueName] | /ve]"); 64 | return; 65 | } 66 | QueryRegistryKeyOrValue(args); 67 | break; 68 | 69 | case "add": 70 | if (args.Length < 2) 71 | { 72 | Console.WriteLine("Usage: REG ADD KeyName [/v ValueName | /ve] [/t Type] [/d Data] [/f]"); 73 | return; 74 | } 75 | AddRegistryKeyOrValue(args); 76 | break; 77 | 78 | default: 79 | Console.WriteLine("Unsupported action. Use import, export, delete, query, or add."); 80 | break; 81 | } 82 | } 83 | 84 | // Helper method to display success messages 85 | static void DisplaySuccessMessage(string detailedMessage) 86 | { 87 | if (isVerbose) 88 | { 89 | Console.WriteLine(detailedMessage); 90 | } 91 | else 92 | { 93 | Console.WriteLine("The operation completed successfully."); 94 | } 95 | } 96 | 97 | // ADD function 98 | static void AddRegistryKeyOrValue(string[] args) 99 | { 100 | string keyPath = null; 101 | string valueName = ""; 102 | string valueData = ""; 103 | RegistryValueKind valueType = RegistryValueKind.String; // Default to REG_SZ 104 | bool force = false; 105 | 106 | // Start processing from args[1], where the key\subkey is located 107 | for (int i = 1; i < args.Length; i++) 108 | { 109 | switch (args[i].ToLower()) 110 | { 111 | case "/v": 112 | valueName = args[++i]; // Next argument is the value name 113 | break; 114 | case "/ve": 115 | valueName = ""; // Empty value name for default value 116 | break; 117 | case "/t": 118 | valueType = ParseValueType(args[++i]); // Next argument is the type 119 | break; 120 | case "/d": 121 | valueData = args[++i]; // Next argument is the data 122 | break; 123 | case "/f": 124 | force = true; // Force flag 125 | break; 126 | default: 127 | if (keyPath == null) keyPath = args[i]; // First positional argument is the keyPath 128 | break; 129 | } 130 | } 131 | 132 | if (keyPath == null) 133 | { 134 | throw new ArgumentException("Key path is required."); 135 | } 136 | 137 | try 138 | { 139 | keyPath = NormalizeKeyPath(keyPath); 140 | using (RegistryKey key = GetBaseRegistryKey(keyPath, writable: true, createSubKey: true)) 141 | { 142 | if (key == null) 143 | { 144 | throw new InvalidOperationException($"Failed to open or create registry key: {keyPath}"); 145 | } 146 | 147 | if (valueName != null) 148 | { 149 | object data = ConvertToRegistryValue(valueType, valueData); 150 | 151 | if (force || key.GetValue(valueName) == null) 152 | { 153 | key.SetValue(valueName, data, valueType); 154 | DisplaySuccessMessage($"Registry value added: {valueName} = {valueData}"); 155 | } 156 | else 157 | { 158 | Console.WriteLine($"Registry value already exists: {valueName}. Use /f to force overwrite."); 159 | } 160 | } 161 | else 162 | { 163 | DisplaySuccessMessage($"Key created: {keyPath}"); 164 | } 165 | } 166 | } 167 | catch (Exception ex) 168 | { 169 | Console.Error.WriteLine($"An error occurred: {ex.Message}"); 170 | } 171 | } 172 | 173 | // IMPORT function 174 | static void ImportRegistryFile(string filePath) 175 | { 176 | try 177 | { 178 | if (!File.Exists(filePath)) 179 | { 180 | Console.Error.WriteLine($"File not found: {filePath}"); 181 | return; 182 | } 183 | 184 | // Detect encoding based on the file content 185 | Encoding encoding = DetectFileEncoding(filePath); 186 | 187 | using (StreamReader reader = new StreamReader(filePath, encoding)) 188 | { 189 | string line; 190 | RegistryKey currentKey = null; 191 | string accumulatedLine = ""; // To accumulate lines with continuation characters 192 | 193 | while ((line = reader.ReadLine()) != null) 194 | { 195 | line = line.Trim(); 196 | 197 | // Skip empty, comment, and header lines 198 | if (string.IsNullOrWhiteSpace(line) || line.StartsWith(";") || line.StartsWith("Windows") || line.StartsWith("REGEDIT")) 199 | continue; 200 | 201 | // Handle line continuation (backslash at the end) 202 | if (line.EndsWith("\\")) 203 | { 204 | accumulatedLine += line.Substring(0, line.Length - 1).Trim(); 205 | continue; // Wait for the next line to continue processing 206 | } 207 | else 208 | { 209 | // Accumulate the last part of the line 210 | accumulatedLine += line.Trim(); 211 | } 212 | 213 | // Now process the complete accumulated line 214 | if (accumulatedLine.StartsWith("[") && accumulatedLine.EndsWith("]")) 215 | { 216 | // It's a key, so we process it as such 217 | string keyPath = accumulatedLine.Trim('[', ']'); 218 | currentKey?.Close(); 219 | 220 | currentKey = CreateOrOpenRegistryKey(keyPath); 221 | } 222 | else if (currentKey != null) 223 | { 224 | ParseAndSetRegistryValue(currentKey, accumulatedLine); 225 | } 226 | 227 | accumulatedLine = ""; 228 | } 229 | 230 | currentKey?.Close(); 231 | } 232 | 233 | DisplaySuccessMessage($"Successfully imported registry from file: {filePath}"); 234 | } 235 | catch (Exception ex) 236 | { 237 | Console.Error.WriteLine($"Error importing registry: {ex.Message}"); 238 | } 239 | } 240 | 241 | // Function to detect encoding by reading the byte order mark (BOM) or file content 242 | static Encoding DetectFileEncoding(string filePath) 243 | { 244 | using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read)) 245 | { 246 | if (file.Length >= 2) 247 | { 248 | byte[] bom = new byte[2]; 249 | file.Read(bom, 0, 2); 250 | 251 | // Check for UTF-16 LE BOM (FF FE) 252 | if (bom[0] == 0xFF && bom[1] == 0xFE) 253 | return Encoding.Unicode; 254 | 255 | // Check for UTF-16 BE BOM (FE FF) 256 | if (bom[0] == 0xFE && bom[1] == 0xFF) 257 | return Encoding.BigEndianUnicode; 258 | } 259 | 260 | // Default to ANSI (UTF-8 without BOM) 261 | return Encoding.Default; 262 | } 263 | } 264 | 265 | static RegistryKey CreateOrOpenRegistryKey(string keyPath) 266 | { 267 | try 268 | { 269 | keyPath = NormalizeKeyPath(keyPath); 270 | 271 | int firstSlashIndex = keyPath.IndexOf('\\'); 272 | if (firstSlashIndex == -1) 273 | { 274 | // No subkey exists, just return the base key 275 | return GetBaseRegistryKey(keyPath, writable: true, createSubKey: true); 276 | } 277 | 278 | string baseKeyName = keyPath.Substring(0, firstSlashIndex); 279 | string subKeyPath = keyPath.Substring(firstSlashIndex + 1); 280 | 281 | // Get the base registry key (e.g., HKEY_CURRENT_USER) 282 | RegistryKey baseKey = GetBaseRegistryKey(baseKeyName, writable: true, createSubKey: true); 283 | if (baseKey == null) 284 | { 285 | throw new InvalidOperationException($"Invalid base registry key: {baseKeyName}"); 286 | } 287 | 288 | // Create the subkey path if it doesn't exist 289 | return CreateSubKeyPath(baseKey, subKeyPath); 290 | } 291 | catch (Exception ex) 292 | { 293 | Console.Error.WriteLine($"Error creating or opening registry key '{keyPath}': {ex.Message}"); 294 | return null; 295 | } 296 | } 297 | 298 | static RegistryKey CreateSubKeyPath(RegistryKey baseKey, string subKeyPath) 299 | { 300 | try 301 | { 302 | // Recursively create or open each subkey in the path 303 | RegistryKey currentKey = baseKey.CreateSubKey(subKeyPath, true); 304 | if (currentKey == null) 305 | { 306 | throw new InvalidOperationException($"Failed to create or open registry subkey: {subKeyPath}"); 307 | } 308 | 309 | return currentKey; 310 | } 311 | catch (Exception ex) 312 | { 313 | Console.Error.WriteLine($"Error creating subkey path '{subKeyPath}': {ex.Message}"); 314 | return null; 315 | } 316 | } 317 | 318 | // EXPORT function 319 | static void ExportRegistryKey(string keyPath, string filePath, bool forceOverwrite) 320 | { 321 | keyPath = NormalizeKeyPath(keyPath); 322 | 323 | try 324 | { 325 | if (File.Exists(filePath) && !forceOverwrite) 326 | { 327 | Console.WriteLine($"File {filePath} already exists. Use /y to overwrite."); 328 | return; 329 | } 330 | 331 | using (RegistryKey key = GetBaseRegistryKey(keyPath)) 332 | { 333 | if (key == null) 334 | { 335 | Console.Error.WriteLine($"Registry key not found: {keyPath}"); 336 | return; 337 | } 338 | 339 | using (StreamWriter writer = new StreamWriter(filePath, false, System.Text.Encoding.Unicode)) 340 | { 341 | writer.WriteLine("Windows Registry Editor Version 5.00\r\n"); 342 | ExportKey(key, keyPath, writer); 343 | } 344 | DisplaySuccessMessage($"Registry exported to file: {filePath}"); 345 | } 346 | } 347 | catch (Exception ex) 348 | { 349 | Console.Error.WriteLine($"Error exporting registry: {ex.Message}"); 350 | } 351 | } 352 | 353 | static string NormalizeKeyPath(string keyPath) 354 | { 355 | // map abbreviations and full names to their full uppercase versions 356 | var keyMappings = new Dictionary(StringComparer.OrdinalIgnoreCase) 357 | { 358 | { "HKLM", "HKEY_LOCAL_MACHINE" }, 359 | { "HKEY_LOCAL_MACHINE", "HKEY_LOCAL_MACHINE" }, 360 | { "HKCU", "HKEY_CURRENT_USER" }, 361 | { "HKEY_CURRENT_USER", "HKEY_CURRENT_USER" }, 362 | { "HKCR", "HKEY_CLASSES_ROOT" }, 363 | { "HKEY_CLASSES_ROOT", "HKEY_CLASSES_ROOT" }, 364 | { "HKU", "HKEY_USERS" }, 365 | { "HKEY_USERS", "HKEY_USERS" }, 366 | { "HKCC", "HKEY_CURRENT_CONFIG" }, 367 | { "HKEY_CURRENT_CONFIG", "HKEY_CURRENT_CONFIG" } 368 | }; 369 | 370 | string[] pathParts = keyPath.Split(new char[] { '\\' }, 2); 371 | 372 | if (keyMappings.ContainsKey(pathParts[0])) 373 | { 374 | pathParts[0] = keyMappings[pathParts[0]]; 375 | } 376 | return pathParts.Length > 1 ? $"{pathParts[0]}\\{pathParts[1]}" : pathParts[0]; 377 | } 378 | 379 | static void ExportKey(RegistryKey key, string keyPath, StreamWriter writer) 380 | { 381 | writer.WriteLine($"[{keyPath}]"); 382 | foreach (string valueName in key.GetValueNames()) 383 | { 384 | object value = key.GetValue(valueName, null, RegistryValueOptions.DoNotExpandEnvironmentNames); 385 | RegistryValueKind kind = key.GetValueKind(valueName); 386 | writer.WriteLine(FormatRegistryValue(valueName, value, kind)); 387 | } 388 | writer.WriteLine(); 389 | 390 | foreach (string subkeyName in key.GetSubKeyNames()) 391 | { 392 | using (RegistryKey subKey = key.OpenSubKey(subkeyName)) 393 | { 394 | if (subKey != null) 395 | { 396 | ExportKey(subKey, $"{keyPath}\\{subkeyName}", writer); 397 | } 398 | } 399 | } 400 | } 401 | 402 | static string FormatRegistryValue(string name, object value, RegistryValueKind kind) 403 | { 404 | string formattedName = string.IsNullOrEmpty(name) ? "@" : $"\"{name.Replace("\\", "\\\\").Replace("\"", "\\\"")}\""; 405 | 406 | switch (kind) 407 | { 408 | case RegistryValueKind.String: 409 | return $"{formattedName}=\"{value.ToString().Replace("\\", "\\\\").Replace("\"", "\\\"")}\""; 410 | 411 | case RegistryValueKind.ExpandString: 412 | string hexExpandString = string.Join(",", BitConverter.ToString(Encoding.Unicode.GetBytes(value.ToString())).Split('-')); 413 | return $"{formattedName}=hex(2):{hexExpandString}"; 414 | 415 | case RegistryValueKind.DWord: 416 | return $"{formattedName}=dword:{((uint)(int)value).ToString("x8")}"; 417 | 418 | case RegistryValueKind.QWord: 419 | ulong qwordValue = Convert.ToUInt64(value); 420 | return $"{formattedName}=hex(b):{string.Join(",", BitConverter.GetBytes(qwordValue).Select(b => b.ToString("x2")))}"; 421 | 422 | case RegistryValueKind.Binary: 423 | return $"{formattedName}=hex:{BitConverter.ToString((byte[])value).Replace("-", ",")}"; 424 | 425 | case RegistryValueKind.MultiString: 426 | string[] multiStrings = (string[])value; 427 | var hexValues = multiStrings.SelectMany(s => Encoding.Unicode.GetBytes(s) 428 | .Select(b => b.ToString("x2")) 429 | .Concat(new[] { "00", "00" })) 430 | .ToList(); 431 | hexValues.AddRange(new[] { "00", "00" }); 432 | return $"{formattedName}=hex(7):{string.Join(",", hexValues)}"; 433 | 434 | case RegistryValueKind.None: 435 | byte[] noneData = value as byte[]; 436 | string hexNone = string.Join(",", noneData.Select(b => b.ToString("x2"))); 437 | return $"{formattedName}=hex(0):{hexNone}"; 438 | 439 | default: 440 | throw new NotSupportedException($"Unsupported registry value type: {kind}"); 441 | } 442 | } 443 | 444 | static void DeleteRegistryKeyOrValue(string[] args) 445 | { 446 | string keyPath = args[1]; 447 | keyPath = NormalizeKeyPath(keyPath); 448 | string valueName = null; 449 | bool deleteAllValues = false; 450 | bool force = args.Contains("/f"); 451 | 452 | if (args.Contains("/va")) 453 | { 454 | deleteAllValues = true; 455 | } 456 | else if (args.Contains("/ve")) 457 | { 458 | valueName = ""; // Default value 459 | } 460 | else if (args.Contains("/v")) 461 | { 462 | valueName = args[Array.IndexOf(args, "/v") + 1]; 463 | } 464 | 465 | try 466 | { 467 | string[] keyParts = keyPath.Split(new char[] { '\\' }, 2); 468 | string root = keyParts[0].ToUpper(); 469 | string subKey = keyParts.Length > 1 ? keyParts[1] : string.Empty; 470 | 471 | using (RegistryKey baseKey = GetBaseRegistryKey(root, writable: true)) 472 | { 473 | if (baseKey == null) 474 | { 475 | throw new ArgumentException($"Could not open the root hive: {root}"); 476 | } 477 | 478 | if (!string.IsNullOrEmpty(subKey)) 479 | { 480 | // Open subKey as writable to delete values within it 481 | using (RegistryKey targetKey = baseKey.OpenSubKey(subKey, writable: true)) 482 | { 483 | if (targetKey == null) 484 | { 485 | Console.Error.WriteLine($"ERROR: The system was unable to find the specified registry key or value."); 486 | return; 487 | } 488 | 489 | if (!force) 490 | { 491 | // Determine prompt based on whether deleting a key or a value 492 | if (deleteAllValues) 493 | { 494 | Console.Write($"Delete all values under the registry key {keyPath} (Yes/No)? "); 495 | } 496 | else if (valueName != null) 497 | { 498 | Console.Write($"Delete the registry value {valueName} (Yes/No)? "); 499 | } 500 | else 501 | { 502 | // Prompt for key deletion 503 | Console.Write($"Permanently delete the registry key {keyPath} (Yes/No)? "); 504 | } 505 | 506 | string response = Console.ReadLine(); 507 | if (string.IsNullOrEmpty(response) || !response.StartsWith("y", StringComparison.OrdinalIgnoreCase)) 508 | { 509 | Console.WriteLine("Operation cancelled."); 510 | return; 511 | } 512 | } 513 | 514 | if (deleteAllValues) 515 | { 516 | foreach (var name in targetKey.GetValueNames()) 517 | { 518 | targetKey.DeleteValue(name, throwOnMissingValue: false); 519 | } 520 | DisplaySuccessMessage($"All values deleted under key: {keyPath}"); 521 | } 522 | else if (valueName != null) 523 | { 524 | if (targetKey.GetValue(valueName) != null) 525 | { 526 | targetKey.DeleteValue(valueName); 527 | DisplaySuccessMessage($"Deleted value '{valueName}' under key: {keyPath}"); 528 | } 529 | else 530 | { 531 | Console.Error.WriteLine($"ERROR: The system was unable to find the specified registry key or value."); 532 | } 533 | } 534 | else 535 | { 536 | // Delete the entire subKey tree 537 | baseKey.DeleteSubKeyTree(subKey, throwOnMissingSubKey: false); 538 | DisplaySuccessMessage($"Deleted key: {keyPath}"); 539 | } 540 | } 541 | } 542 | else 543 | { 544 | Console.WriteLine("Cannot delete the root hive itself."); 545 | } 546 | } 547 | } 548 | catch (Exception ex) 549 | { 550 | Console.Error.WriteLine($"Error deleting registry key or value: {ex.Message}"); 551 | } 552 | } 553 | 554 | // QUERY function 555 | static void QueryRegistryKeyOrValue(string[] args) 556 | { 557 | string keyPath = args[1]; 558 | keyPath = NormalizeKeyPath(keyPath); 559 | string valueName = args.Contains("/v") ? args[Array.IndexOf(args, "/v") + 1] : null; 560 | bool queryDefaultValue = args.Contains("/ve"); 561 | bool isRecursive = args.Contains("/s"); // Check if /s is passed for recursive query 562 | bool hasValues = false; 563 | string myKey = @"HKEY_CURRENT_USER\Software\CSReg"; 564 | try { Registry.CurrentUser.OpenSubKey(@"Software\CSReg", true)?.DeleteValue("RetVal", false); } catch { } 565 | 566 | try 567 | { 568 | using (RegistryKey key = GetBaseRegistryKey(keyPath)) 569 | { 570 | if (key == null) 571 | { 572 | Console.Error.WriteLine($"ERROR: The system was unable to find the specified registry key or value."); 573 | return; 574 | } 575 | 576 | Console.WriteLine(); // Always print one blank line at the start 577 | 578 | if (valueName != null) // Query a specific value 579 | { 580 | object value = key.GetValue(valueName, null, RegistryValueOptions.DoNotExpandEnvironmentNames); 581 | if (value == null) 582 | { 583 | Console.Error.WriteLine($"ERROR: The system was unable to find the specified registry key or value."); 584 | } 585 | else 586 | { 587 | RegistryValueKind valueKind = key.GetValueKind(valueName); 588 | Console.WriteLine(keyPath); // Print the full registry key path 589 | Console.WriteLine($" {valueName} {FormatRegistryValueType(valueKind)} {FormatRegistryValueData(value, valueKind)}"); 590 | Console.WriteLine(); // print blank line 591 | Registry.SetValue(myKey, "RetVal", $"{value}", RegistryValueKind.String); 592 | } 593 | } 594 | else if (queryDefaultValue) // Query the default value 595 | { 596 | object defaultValue = key.GetValue(null, null, RegistryValueOptions.DoNotExpandEnvironmentNames); 597 | if (defaultValue != null) 598 | { 599 | RegistryValueKind defaultValueKind = key.GetValueKind(null); 600 | Console.WriteLine(keyPath); // Print the full registry key path 601 | Console.WriteLine($" (Default) {FormatRegistryValueType(defaultValueKind)} {FormatRegistryValueData(defaultValue, defaultValueKind)}"); 602 | Console.WriteLine(); // print blank line 603 | Registry.SetValue(myKey, "RetVal", $"{defaultValue}", RegistryValueKind.String); 604 | } 605 | else 606 | { 607 | Console.Error.WriteLine($"ERROR: The system was unable to find the specified registry key or value."); 608 | } 609 | } 610 | else 611 | { 612 | // If recursive, call recursive query method 613 | if (isRecursive) 614 | { 615 | QueryRegistryRecursively(key, keyPath); 616 | } 617 | else 618 | { 619 | // Query and print all values 620 | foreach (var name in key.GetValueNames()) 621 | { 622 | if (!hasValues) 623 | { 624 | Console.WriteLine(keyPath); // Print key path 625 | hasValues = true; 626 | } 627 | 628 | object value = key.GetValue(name, null, RegistryValueOptions.DoNotExpandEnvironmentNames); 629 | RegistryValueKind kind = key.GetValueKind(name); 630 | 631 | string valueNameToPrint = string.IsNullOrEmpty(name) ? "(Default)" : name; 632 | Console.WriteLine($" {valueNameToPrint} {FormatRegistryValueType(kind)} {FormatRegistryValueData(value, kind)}"); 633 | } 634 | 635 | // Print a blank line after values if any were found 636 | if (hasValues) Console.WriteLine(); 637 | 638 | // Query and print subkeys 639 | foreach (var subkeyName in key.GetSubKeyNames()) 640 | { 641 | Console.WriteLine($"{keyPath}\\{subkeyName}"); 642 | } 643 | } 644 | } 645 | } 646 | } 647 | catch (Exception ex) 648 | { 649 | Console.Error.WriteLine($"Error querying registry: {ex.Message}"); 650 | } 651 | } 652 | 653 | // Recursive query method for subkeys and values 654 | static void QueryRegistryRecursively(RegistryKey key, string keyPath) 655 | { 656 | bool hasValues = false; 657 | 658 | // Print values under the current key 659 | foreach (var name in key.GetValueNames()) 660 | { 661 | if (!hasValues) 662 | { 663 | Console.WriteLine(keyPath); // Print key path 664 | hasValues = true; 665 | } 666 | 667 | object value = key.GetValue(name, null, RegistryValueOptions.DoNotExpandEnvironmentNames); 668 | RegistryValueKind kind = key.GetValueKind(name); 669 | 670 | string valueNameToPrint = string.IsNullOrEmpty(name) ? "(Default)" : name; 671 | Console.WriteLine($" {valueNameToPrint} {FormatRegistryValueType(kind)} {FormatRegistryValueData(value, kind)}"); 672 | } 673 | 674 | // If values were printed, add a blank line after them 675 | if (hasValues) 676 | { 677 | Console.WriteLine(); 678 | } 679 | 680 | // Recurse into subkeys 681 | foreach (var subkeyName in key.GetSubKeyNames()) 682 | { 683 | string subkeyPath = $"{keyPath}\\{subkeyName}"; 684 | using (RegistryKey subkey = key.OpenSubKey(subkeyName)) 685 | { 686 | if (subkey != null) 687 | { 688 | QueryRegistryRecursively(subkey, subkeyPath); // Recurse into the subkey 689 | } 690 | } 691 | } 692 | } 693 | 694 | static string FormatRegistryValueType(RegistryValueKind kind) 695 | { 696 | switch (kind) 697 | { 698 | case RegistryValueKind.String: return "REG_SZ"; 699 | case RegistryValueKind.ExpandString: return "REG_EXPAND_SZ"; 700 | case RegistryValueKind.DWord: return "REG_DWORD"; 701 | case RegistryValueKind.QWord: return "REG_QWORD"; 702 | case RegistryValueKind.Binary: return "REG_BINARY"; 703 | case RegistryValueKind.MultiString: return "REG_MULTI_SZ"; 704 | case RegistryValueKind.None: return "REG_NONE"; 705 | default: return "UNKNOWN_TYPE"; 706 | } 707 | } 708 | 709 | static string FormatRegistryValueData(object value, RegistryValueKind kind) 710 | { 711 | switch (kind) 712 | { 713 | case RegistryValueKind.String: 714 | case RegistryValueKind.ExpandString: 715 | return value.ToString(); 716 | 717 | case RegistryValueKind.DWord: 718 | return "0x" + ((uint)(int)value).ToString("x"); 719 | 720 | case RegistryValueKind.QWord: 721 | return "0x" + ((ulong)(long)value).ToString("x"); 722 | 723 | case RegistryValueKind.Binary: 724 | return BitConverter.ToString((byte[])value).Replace("-", ""); 725 | 726 | case RegistryValueKind.MultiString: 727 | return string.Join("\\0", (string[])value); 728 | 729 | case RegistryValueKind.None: 730 | return ""; // No data for REG_NONE 731 | 732 | default: 733 | throw new NotSupportedException($"Unsupported registry value type: {kind}"); 734 | } 735 | } 736 | 737 | static RegistryKey GetBaseRegistryKey(string keyPath, bool writable = false, bool createSubKey = false) 738 | { 739 | string[] keyParts = keyPath.Split(new char[] { '\\' }, 2); // Split into root and subkey 740 | string root = keyParts[0].ToUpper(); 741 | string subKey = keyParts.Length > 1 ? keyParts[1] : string.Empty; // If there's no subkey, handle it as empty 742 | 743 | RegistryKey baseKey; 744 | 745 | switch (root) 746 | { 747 | case "HKEY_LOCAL_MACHINE": 748 | baseKey = Registry.LocalMachine; 749 | break; 750 | case "HKEY_CURRENT_USER": 751 | baseKey = Registry.CurrentUser; 752 | break; 753 | case "HKEY_CLASSES_ROOT": 754 | baseKey = Registry.ClassesRoot; 755 | break; 756 | case "HKEY_USERS": 757 | baseKey = Registry.Users; 758 | break; 759 | case "HKEY_CURRENT_CONFIG": 760 | baseKey = Registry.CurrentConfig; 761 | break; 762 | default: 763 | throw new NotSupportedException($"Unsupported root key: {root}"); 764 | } 765 | 766 | if (string.IsNullOrEmpty(subKey)) return baseKey; 767 | 768 | if (createSubKey) 769 | { 770 | return baseKey.CreateSubKey(subKey, writable); 771 | } 772 | else 773 | { 774 | return baseKey.OpenSubKey(subKey, writable); 775 | } 776 | } 777 | 778 | static RegistryValueKind ParseValueType(string type) 779 | { 780 | switch (type.ToUpper()) 781 | { 782 | case "REG_SZ": 783 | return RegistryValueKind.String; 784 | case "REG_MULTI_SZ": 785 | return RegistryValueKind.MultiString; 786 | case "REG_EXPAND_SZ": 787 | return RegistryValueKind.ExpandString; 788 | case "REG_DWORD": 789 | return RegistryValueKind.DWord; 790 | case "REG_QWORD": 791 | return RegistryValueKind.QWord; 792 | case "REG_BINARY": 793 | return RegistryValueKind.Binary; 794 | case "REG_NONE": 795 | return RegistryValueKind.None; 796 | default: 797 | throw new NotSupportedException($"Unsupported registry value type: {type}"); 798 | } 799 | } 800 | 801 | static object ConvertToRegistryValue(RegistryValueKind kind, string data) 802 | { 803 | switch (kind) 804 | { 805 | case RegistryValueKind.String: 806 | case RegistryValueKind.ExpandString: 807 | return data; 808 | 809 | case RegistryValueKind.DWord: 810 | return Convert.ToUInt32(data, 16); 811 | 812 | case RegistryValueKind.QWord: 813 | return Convert.ToUInt64(data, 16); 814 | 815 | case RegistryValueKind.MultiString: 816 | return data.Split(new[] { "\\0" }, StringSplitOptions.None); 817 | 818 | case RegistryValueKind.Binary: 819 | return Enumerable.Range(0, data.Length / 2).Select(x => Convert.ToByte(data.Substring(x * 2, 2), 16)).ToArray(); 820 | 821 | case RegistryValueKind.None: 822 | return Encoding.Unicode.GetBytes(data + '\0'); 823 | 824 | default: 825 | throw new NotSupportedException($"Unsupported registry value kind: {kind}"); 826 | } 827 | } 828 | 829 | static void ParseAndSetRegistryValue(RegistryKey key, string line) 830 | { 831 | string name; string valueData; bool empty; 832 | 833 | void GetNameAndData(string pattern) 834 | { 835 | string[] parts = line.Split(new string[] { pattern }, 2, StringSplitOptions.None); 836 | name = parts[0].Substring(1).Replace("\\\"", "\"").Replace("\\\\", "\\"); 837 | if (name == "@") name = null; 838 | valueData = parts[1].Substring(0, parts[1].Length); 839 | if (valueData.EndsWith("\"")) valueData = valueData.Substring(0, valueData.Length - 1); 840 | valueData = valueData.Replace("\\\"", "\"").Replace("\\\\", "\\"); 841 | empty = valueData.Length == 0; 842 | } 843 | 844 | void TrimThis(string pattern) 845 | { 846 | if (valueData.EndsWith(pattern)) valueData = valueData.Substring(0, valueData.Length - pattern.Length); 847 | if (valueData == "00,00") valueData = ""; 848 | empty = valueData.Length == 0; 849 | } 850 | 851 | if (line.StartsWith("@=")) 852 | { 853 | line = $"\"@\"{line.Substring(1)}"; 854 | } 855 | 856 | string regType = string.Empty; 857 | 858 | if (line.Contains("\"=\"")) regType = "REG_SZ"; 859 | else if (line.Contains("\"=dword:")) regType = "REG_DWORD"; 860 | else if (line.Contains("\"=hex(b):")) regType = "REG_QWORD"; 861 | else if (line.Contains("\"=hex:")) regType = "REG_BINARY"; 862 | else if (line.Contains("\"=hex(2):")) regType = "REG_EXPAND_SZ"; 863 | else if (line.Contains("\"=hex(7):")) regType = "REG_MULTI_SZ"; 864 | else if (line.Contains("\"=hex(0):")) regType = "REG_NONE"; 865 | 866 | switch (regType) 867 | { 868 | case "REG_SZ": 869 | GetNameAndData("\"=\""); 870 | key.SetValue(name, valueData, RegistryValueKind.String); 871 | break; 872 | 873 | case "REG_DWORD": 874 | GetNameAndData("\"=dword:"); 875 | uint dwordValue = Convert.ToUInt32(valueData, 16); 876 | key.SetValue(name, (int)dwordValue, RegistryValueKind.DWord); 877 | break; 878 | 879 | case "REG_QWORD": 880 | GetNameAndData("\"=hex(b):"); 881 | string[] bytePairs = valueData.Split(new[] { ',' }); 882 | ulong qwordValue = 0; 883 | for (int i = 0; i < bytePairs.Length; i++) 884 | { 885 | qwordValue |= ((ulong)Convert.ToByte(bytePairs[i], 16)) << (i * 8); 886 | } 887 | key.SetValue(name, qwordValue, RegistryValueKind.QWord); 888 | break; 889 | 890 | case "REG_BINARY": 891 | GetNameAndData("\"=hex:"); 892 | if (empty) 893 | { 894 | key.SetValue(name, new byte[0], RegistryValueKind.Binary); 895 | } 896 | else 897 | { 898 | byte[] binaryData = valueData.Split(',').Select(h => Convert.ToByte(h, 16)).ToArray(); 899 | key.SetValue(name, binaryData, RegistryValueKind.Binary); 900 | } 901 | break; 902 | 903 | case "REG_EXPAND_SZ": 904 | GetNameAndData("\"=hex(2):"); 905 | TrimThis(",00,00"); 906 | TrimThis(",00,00"); 907 | 908 | if (empty) 909 | { 910 | key.SetValue(name, string.Empty, RegistryValueKind.ExpandString); 911 | } 912 | else 913 | { 914 | byte[] binaryData = valueData.Split(',').Select(h => Convert.ToByte(h, 16)).ToArray(); 915 | string expandSzValue = Encoding.Unicode.GetString(binaryData); 916 | key.SetValue(name, expandSzValue, RegistryValueKind.ExpandString); 917 | } 918 | break; 919 | 920 | case "REG_MULTI_SZ": 921 | GetNameAndData("\"=hex(7):"); 922 | TrimThis(",00,00"); 923 | TrimThis(",00,00"); 924 | 925 | if (empty) 926 | { 927 | key.SetValue(name, new string[] { string.Empty }, RegistryValueKind.MultiString); 928 | } 929 | else 930 | { 931 | byte[] binaryData = valueData.Split(',').Select(h => Convert.ToByte(h, 16)).ToArray(); 932 | string multiSzValue = Encoding.Unicode.GetString(binaryData); 933 | string[] multiStringArray = multiSzValue.Split(new[] { '\0' }); 934 | key.SetValue(name, multiStringArray, RegistryValueKind.MultiString); 935 | } 936 | break; 937 | 938 | case "REG_NONE": 939 | GetNameAndData("\"=hex(0):"); 940 | if (empty) 941 | { 942 | key.SetValue(name, Encoding.Unicode.GetBytes("" + '\0'), RegistryValueKind.None); 943 | } 944 | else 945 | { 946 | byte[] binaryData = valueData.Split(',').Select(h => Convert.ToByte(h, 16)).ToArray(); 947 | key.SetValue(name, binaryData, RegistryValueKind.None); 948 | } 949 | break; 950 | 951 | default: 952 | throw new InvalidOperationException("Unknown registry value type."); 953 | } 954 | } 955 | } 956 | } 957 | -------------------------------------------------------------------------------- /src/313/CloseExplorerWindows.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | class Program 5 | { 6 | // Import the necessary Windows API functions 7 | [DllImport("user32.dll", SetLastError = true)] 8 | public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 9 | 10 | [DllImport("user32.dll", SetLastError = true)] 11 | [return: MarshalAs(UnmanagedType.Bool)] 12 | public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 13 | 14 | [DllImport("user32.dll")] 15 | public static extern bool IsWindowVisible(IntPtr hWnd); 16 | 17 | // Message constants 18 | const uint WM_CLOSE = 0x0010; 19 | 20 | static void Main() 21 | { 22 | // Look for windows with the class name "CabinetWClass" (Explorer windows) 23 | IntPtr hWnd = FindWindow("CabinetWClass", null); 24 | 25 | // Loop to find and close all open Explorer windows 26 | while (hWnd != IntPtr.Zero) 27 | { 28 | try 29 | { 30 | // Check if the window is visible 31 | if (IsWindowVisible(hWnd)) 32 | { 33 | // Send the WM_CLOSE message to close the window 34 | PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); 35 | Console.WriteLine("Closed an Explorer window"); 36 | } 37 | 38 | // Find the next Explorer window 39 | hWnd = FindWindowEx(IntPtr.Zero, hWnd, "CabinetWClass", null); 40 | } 41 | catch (Exception ex) 42 | { 43 | Console.WriteLine($"Error closing window: {ex.Message}"); 44 | } 45 | } 46 | } 47 | 48 | // Import FindWindowEx to get the next window of the same class 49 | [DllImport("user32.dll", SetLastError = true)] 50 | public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 51 | } 52 | -------------------------------------------------------------------------------- /src/313/GetMoreProperties.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.IO; 4 | using System.Collections.Generic; 5 | 6 | namespace GetMoreProperties 7 | { 8 | internal class Program 9 | { 10 | static void Main() 11 | { 12 | string tempPath = Path.GetTempPath(); 13 | string filePath = Path.Combine(tempPath, "Properties.tmp"); 14 | 15 | List matchingProperties = new List(); 16 | 17 | PSEnumeratePropertyDescriptions(PROPDESC_ENUMFILTER.PDEF_ALL, typeof(IPropertyDescriptionList).GUID, out var list); 18 | for (var i = 0; i < list.GetCount(); i++) 19 | { 20 | var pd = list.GetAt(i, typeof(IPropertyDescription).GUID); 21 | 22 | pd.GetDisplayName(out var p); 23 | if (p != IntPtr.Zero) 24 | { 25 | var viewable = pd.GetTypeFlags(PROPDESC_TYPE_FLAGS.PDTF_ISVIEWABLE) == PROPDESC_TYPE_FLAGS.PDTF_ISVIEWABLE; 26 | 27 | if (viewable) 28 | { 29 | string dname = Marshal.PtrToStringUni(p); 30 | Marshal.FreeCoTaskMem(p); 31 | 32 | pd.GetCanonicalName(out p); 33 | string cname = Marshal.PtrToStringUni(p); 34 | Marshal.FreeCoTaskMem(p); 35 | 36 | if (!cname.StartsWith("System") && !cname.StartsWith("Icaros")) 37 | { 38 | matchingProperties.Add($"{dname};.{cname}"); 39 | } 40 | } 41 | } 42 | } 43 | 44 | if (matchingProperties.Count > 0) 45 | { 46 | using (StreamWriter writer = new StreamWriter(filePath, false, System.Text.Encoding.Unicode)) 47 | { 48 | foreach (var property in matchingProperties) 49 | { 50 | writer.WriteLine(property); 51 | } 52 | } 53 | } 54 | } 55 | 56 | public struct PROPERTYKEY 57 | { 58 | public Guid fmtid; 59 | public int pid; 60 | } 61 | 62 | public enum PROPDESC_ENUMFILTER 63 | { 64 | PDEF_ALL = 0, 65 | PDEF_SYSTEM = 1, 66 | PDEF_NONSYSTEM = 2, 67 | PDEF_VIEWABLE = 3, 68 | PDEF_QUERYABLE = 4, 69 | PDEF_INFULLTEXTQUERY = 5, 70 | PDEF_COLUMN = 6, 71 | } 72 | 73 | [Flags] 74 | public enum PROPDESC_TYPE_FLAGS 75 | { 76 | PDTF_DEFAULT = 0, 77 | PDTF_MULTIPLEVALUES = 0x1, 78 | PDTF_ISINNATE = 0x2, 79 | PDTF_ISGROUP = 0x4, 80 | PDTF_CANGROUPBY = 0x8, 81 | PDTF_CANSTACKBY = 0x10, 82 | PDTF_ISTREEPROPERTY = 0x20, 83 | PDTF_INCLUDEINFULLTEXTQUERY = 0x40, 84 | PDTF_ISVIEWABLE = 0x80, 85 | PDTF_ISQUERYABLE = 0x100, 86 | PDTF_CANBEPURGED = 0x200, 87 | PDTF_SEARCHRAWVALUE = 0x400, 88 | PDTF_DONTCOERCEEMPTYSTRINGS = 0x800, 89 | PDTF_ALWAYSINSUPPLEMENTALSTORE = 0x1000, 90 | PDTF_ISSYSTEMPROPERTY = unchecked((int)0x80000000), 91 | PDTF_MASK_ALL = unchecked((int)0x80001fff), 92 | } 93 | 94 | [DllImport("propsys")] 95 | public static extern int PSEnumeratePropertyDescriptions(PROPDESC_ENUMFILTER filterOn, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IPropertyDescriptionList ppv); 96 | 97 | [ComImport, Guid("1F9FC1D0-C39B-4B26-817F-011967D3440E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 98 | public interface IPropertyDescriptionList 99 | { 100 | int GetCount(); 101 | [return: MarshalAs(UnmanagedType.Interface)] 102 | IPropertyDescription GetAt(int iElem, [MarshalAs(UnmanagedType.LPStruct)] Guid riid); 103 | } 104 | 105 | [ComImport, Guid("6F79D558-3E96-4549-A1D1-7D75D2288814"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 106 | public interface IPropertyDescription 107 | { 108 | PROPERTYKEY GetPropertyKey(); 109 | [PreserveSig] int GetCanonicalName(out IntPtr zPtr); 110 | int GetPropertyType(); 111 | [PreserveSig] int GetDisplayName(out IntPtr zPtr); 112 | [PreserveSig] int GetEditInvitation(out IntPtr zPtr); 113 | PROPDESC_TYPE_FLAGS GetTypeFlags(PROPDESC_TYPE_FLAGS mask); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/313/Modal.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 299 | 300 | 314 | 315 | 316 | 317 | 318 |
319 |
320 | 321 |
322 |
323 |
324 | 325 |
326 |
327 |
328 | 329 |
330 |
331 |
332 | 333 |
334 |
335 |
336 |
337 |
338 |
339 | 340 | 341 |
342 |
343 | 344 |
345 |
346 |
347 |
348 | 349 |
350 | 351 |
352 |
353 |
354 |

355 |
356 |


357 | 358 |
359 |
360 | 361 | 362 | -------------------------------------------------------------------------------- /src/313/UAC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesFerch/WinSetView/aee13bade40bed1db46cd640e2d6ea03524addd3/src/313/UAC.png -------------------------------------------------------------------------------- /src/313/WinSetView.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesFerch/WinSetView/aee13bade40bed1db46cd640e2d6ea03524addd3/src/313/WinSetView.ico -------------------------------------------------------------------------------- /src/313/WinSetView.ps1: -------------------------------------------------------------------------------- 1 | # WinSetView (Globally Set Explorer Folder Views) 2 | # Les Ferch, lesferch@gmail.com, 2021 - 2025 3 | # WinSetView.ps1 (Powershell script to set selected views) 4 | 5 | # One command line paramater is supported 6 | # Provide INI file name to set Explorer views 7 | # Provide REG file name to restore Explorer views from backup 8 | 9 | Param ( 10 | $File = '' 11 | ) 12 | 13 | Set-StrictMode -Off 14 | 15 | #$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" 16 | 17 | $Constrained = $false 18 | If ($ExecutionContext.SessionState.LanguageMode -eq "ConstrainedLanguage") {$Constrained = $true} 19 | 20 | If (-Not $Constrained) {$host.ui.RawUI.WindowTitle = "WinSetView"} 21 | 22 | # Read entire INI file into a dictionary object 23 | 24 | Function Get-IniContent ($FilePath) { 25 | $ini = @{} 26 | Switch -regex -file $FilePath { 27 | '^\[(.+)\]' # Section 28 | { 29 | $section = $matches[1] 30 | $ini[$section] = @{} 31 | } 32 | '(.+?)\s*=(.*)' # Key 33 | { 34 | $name,$value = $matches[1..2] 35 | $ini[$section][$name] = $value 36 | } 37 | } 38 | Return $ini 39 | } 40 | 41 | # Determine Windows version (also works for Windows Server) 42 | # Treat Windows 11 same as Windows 10 because they have same folder types and properties 43 | 44 | $Key = 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion' 45 | $Value = 'CurrentVersion' 46 | $NTVer = (Get-ItemProperty -Path $Key -Name $Value).$Value 47 | $Value = 'CurrentBuild' 48 | $CurBld = [Int](Get-ItemProperty -Path $Key -Name $Value).$Value 49 | $Value = 'UBR' 50 | $UBR = [Int](Get-ItemProperty -Path $Key -Name $Value -ErrorAction SilentlyContinue).$Value 51 | If ($NTVer -eq '6.1') {$WinVer = '7'} 52 | If (($NTVer -eq '6.2') -Or ($NTVer -eq '6.3')) {$WinVer = '8'} 53 | $Value = 'CurrentMajorVersionNumber' 54 | Try {[Int]$MajVer = (Get-ItemProperty -ErrorAction Stop -Path $Key -Name $Value).$Value} 55 | Catch {$MajVer = 0} 56 | If ($MajVer -ge 10) {$WinVer = '10'} 57 | 58 | If (($WinVer -ne '7') -And ($WinVer -ne '8') -And ($WinVer -ne '10')){ 59 | Write-Host `n'Windows 7, 8, 10 or higher is required.'`n 60 | Read-Host -Prompt 'Press Enter to continue' 61 | Exit 62 | } 63 | 64 | # Windows 7 includes Powershell 2 so this check should never fail 65 | 66 | If ($PSVersionTable.PSVersion.Major -lt 2) { 67 | Write-Host `n'Powershell 2 or higher is required.'`n 68 | Read-Host -Prompt 'Press Enter to continue' 69 | Exit 70 | } 71 | 72 | # Verify INI or REG file is supplied on the command line 73 | 74 | $FileExt = '' 75 | If ($File.Length -gt 4) {$FileExt = $File.SubString($File.Length-4)} 76 | 77 | If (-Not(($FileExt -eq '.ini') -Or ($FileExt -eq '.reg'))) { 78 | Write-Host `n'No INI or REG file supplied on command line.'`n 79 | Read-Host -Prompt 'Press Enter to continue' 80 | Exit 81 | } 82 | 83 | # Create PSScriptRoot variable if not exist (i.e. PowerShell 2) 84 | 85 | If (!$PSScriptRoot) {$PSScriptRoot = Split-Path $Script:MyInvocation.MyCommand.Path -Parent} 86 | 87 | # Make sure we can access the INI (or REG) file 88 | 89 | set-location $PSScriptRoot 90 | 91 | If (-Not(Test-Path -Path $File)) { 92 | Write-Host `n"File not found: $File"`n 93 | Read-Host -Prompt 'Press Enter to continue' 94 | Exit 95 | } 96 | 97 | If ($Constrained) { 98 | Write-Host `n"Settings on this computer put PowerShell in Constrained Language Mode." 99 | Write-Host "Some steps may take a bit longer to work around this restriction." 100 | } 101 | 102 | #Keys for use with Reg.exe (or CSReg.exe) command line 103 | $BagM = 'HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU' 104 | $Bags = 'HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags' 105 | $Shel = 'HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell' 106 | $Bag1 = 'HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\1\Shell\{5C4F28B5-F869-4E84-8E60-F11DB97C5CC7}' 107 | $Bag2 = 'HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\2\Shell\{5C4F28B5-F869-4E84-8E60-F11DB97C5CC7}' 108 | $Strm = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams' 109 | $Defs = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Defaults' 110 | $CUFT = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes' 111 | $LMFT = 'HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes' 112 | $Advn = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' 113 | $Clcm = 'HKCU\Software\Classes\CLSID\{86CA1AA0-34AA-4E8B-A509-50C905BAE2A2}' 114 | $Srch = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Search' 115 | $Srhl = 'HKCU\Software\Microsoft\Windows\CurrentVersion\SearchSettings' 116 | $Srdc = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Feeds\DSB' 117 | $BwgM = 'HKCU\Software\Microsoft\Windows\Shell\BagMRU' 118 | $Bwgs = 'HKCU\Software\Microsoft\Windows\Shell\Bags' 119 | $Desk = 'HKCU\Software\Microsoft\Windows\Shell\Bags\1\Desktop' 120 | $TBar = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Desktop' 121 | $Lets = 'HKCU\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement' 122 | $Remd = 'HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 123 | $E10A = 'HKCU\Software\Classes\CLSID\{2aa9162e-c906-4dd9-ad0b-3d24a8eef5a0}' 124 | $E10B = 'HKCU\Software\Classes\CLSID\{6480100b-5a83-4d1e-9f69-8ae5a88e9a33}' 125 | $ESTR = 'HKCU\Software\Classes\CLSID\{52205fd8-5dfb-447d-801a-d0b52f2e83e1}' 126 | $ESTC = 'HKCU\Software\Classes\CLSID\{52205fd8-5dfb-447d-801a-d0b52f2e83e1}\shell\OpenNewWindow\command' 127 | $CCMH = 'HKCU\Software\Classes\AllFileSystemObjects\shellex\ContextMenuHandlers\{C2FBB630-2971-11D1-A18C-00C04FD75D13}' 128 | $MCMH = 'HKCU\Software\Classes\AllFileSystemObjects\shellex\ContextMenuHandlers\{C2FBB631-2971-11D1-A18C-00C04FD75D13}' 129 | $UPol = 'HKCU\Software\Policies\Microsoft\Windows\Explorer' 130 | 131 | #Keys for use with PowerShell 132 | $ShPS = 'HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell' 133 | 134 | #Keys for building REG files 135 | $ImpR = '[HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\' 136 | 137 | #File paths 138 | $TempDir = "$env:TEMP" 139 | $AppData = "$env:APPDATA\WinSetView" 140 | $RegFile1 = "$TempDir\WinSetView1.reg" 141 | $RegFile2 = "$TempDir\WinSetView2.reg" 142 | $T1 = "$TempDir\WinSetView1.tmp" 143 | $T2 = "$TempDir\WinSetView2.tmp" 144 | $T3 = "$TempDir\WinSetView3.tmp" 145 | $T4 = "$TempDir\WinSetView4.tmp" 146 | $T5 = "$TempDir\WinSetView5.tmp" 147 | $T6 = "$TempDir\WinSetView6.tmp" 148 | $T7 = "$TempDir\WinSetView7.tmp" 149 | $ShellBak = "$TempDir\ShellBak.reg" 150 | $DeskBak = "$TempDir\DeskBak.reg" 151 | $TBarBak = "$TempDir\TBarBak.reg" 152 | $TimeStr = (get-date).ToString('yyyy-MM-dd-HHmm-ss') 153 | $RegExe = "$env:SystemRoot\System32\Reg.exe" 154 | $CmdExe = "$env:SystemRoot\System32\Cmd.exe" 155 | $IcaclsExe = "$env:SystemRoot\System32\Icacls.exe" 156 | $KillExe = "$env:SystemRoot\System32\TaskKill.exe" 157 | $UAppData = "$env:UserProfile\AppData" 158 | $CSRegExe = "$PSScriptRoot\AppParts\CSReg.exe" 159 | $ViveExe = "$PSScriptRoot\AppParts\ViVeTool.exe" 160 | $CloseExpW = "$PSScriptRoot\AppParts\CloseExplorerWindows.exe" 161 | 162 | function Get-ShortPath($Path) { 163 | return (-join (& $CmdExe /c "for %p in ("""$Path""") do @echo:%~sp")).Trim() 164 | } 165 | 166 | $CSRegExe = Get-ShortPath($CSRegExe) 167 | $ViveExe = Get-ShortPath($ViveExe) 168 | $CloseExpW = Get-ShortPath($CloseExpW) 169 | 170 | $C1=''; $C2=''; $C3=''; $C4=''; $C5='' 171 | 172 | $regCheck = & $RegExe query HKU 2>$Null 173 | if ($regCheck -eq $Null) { 174 | $RegExe = $CSRegExe 175 | If (-Not(Test-Path -Path $RegExe)) { 176 | Write-Host `n"File not found: $RegExe"`n 177 | Read-Host -Prompt 'Press Enter to continue' 178 | Exit 179 | } 180 | } 181 | 182 | & $CloseExpW 183 | 184 | If ($PSVersionTable.PSVersion.Major -lt 5) { 185 | $userSID = (Get-WmiObject -Class Win32_UserAccount -Filter "Name='$env:UserName'").SID 186 | } 187 | Else { 188 | try { $userSID = (Get-CimInstance -ErrorAction Stop -ClassName Win32_UserAccount -Filter "Name='$env:UserName'").SID } 189 | catch { 190 | $key = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry64) 191 | $subKey = $key.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI") 192 | $userSID = $subKey.GetValue("LastLoggedOnUserSID") 193 | } 194 | } 195 | 196 | $PolE = "HKU\$userSID\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" 197 | $PolEM = "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" 198 | $PolL = "HKU\$userSID\Software\Microsoft\Windows\CurrentVersion\Policies\ComDlg32\PlacesBar" 199 | 200 | # Use script folder if we have write access. Otherwise use AppData folder. 201 | 202 | $TestFile = "$PSScriptRoot\$TimeStr.txt" 203 | Try {[io.file]::OpenWrite($TestFile).close()} 204 | Catch {} 205 | If (Test-Path -Path $TestFile) { 206 | Remove-Item $TestFile 207 | $AppData = "$PSScriptRoot\AppData" 208 | } 209 | $BakFile = "$AppData\Backup\$TimeStr.reg" 210 | $Custom = "$AppData\WinSetViewCustom.reg" 211 | 212 | Function AdjustPrefix($String) { 213 | $String = $String.Replace("System.Icaros.","Icaros.") 214 | $String = $String.Replace("System..","") 215 | Return $String 216 | } 217 | 218 | Function ResetThumbCache { 219 | $ThumbCacheFiles = "$Env:LocalAppData\Microsoft\Windows\Explorer\thumbcache_*.db" 220 | & $IcaclsExe $ThumbCacheFiles /grant Everyone:F >$Null 2>$Null 221 | Remove-Item -Force -ErrorAction SilentlyContinue $ThumbCacheFiles 222 | } 223 | 224 | Function ResetStoreAppViews { 225 | $Exclude = 'WindowsTerminal','WebViewHost','MSTeams','Win32Bridge.Server','PhoneExperienceHost','ClipChamp','ClipChamp.CLI' 226 | $Pkgs = "$env:LocalAppData\Packages" 227 | if (-Not(Test-Path -Path $Pkgs)) {return} 228 | If ($Constrained) {KillStoreAppsConstrained} Else {KillStoreApps} 229 | Get-ChildItem $Pkgs -Directory | ForEach-Object { 230 | Remove-Item -Force -ErrorAction SilentlyContinue "$Pkgs\$_\SystemAppData\Helium\UserClasses.dat" 231 | } 232 | } 233 | 234 | Function KillStoreApps { 235 | $Stor = 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store' 236 | if (-Not(Test-Path -Path $Stor)) {return} 237 | $Key = Get-Item -Path $Stor 238 | ForEach ($ValueName in $($Key.GetValueNames())) { 239 | If ($ValueName -match 'c:\\program files\\windowsapps\\') { 240 | $FileName = Split-Path $ValueName -Leaf 241 | $FileNameBase = $FileName.ToLower().Replace(".exe","") 242 | If ($Exclude -NotContains $FileNameBase) { 243 | & $KillExe /im $FileName >$Null 2>$Null 244 | } 245 | } 246 | } 247 | } 248 | 249 | Function KillStoreAppsConstrained { 250 | $Stor = 'HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store' 251 | $registryValues = & $RegExe query $Stor 252 | $registryValues | ForEach-Object { 253 | $parts = $_.Trim() -split " " 254 | $valueName = $parts[0] 255 | if ($valueName -match 'c:\\program files\\windowsapps\\') { 256 | $FileName = Split-Path $valueName -Leaf 257 | $FileNameBase = $FileName.ToLower().Replace(".exe","") 258 | if ($Exclude -NotContains $FileNameBase) { 259 | & $KillExe /im $FileName >$Null 2>$Null 260 | } 261 | } 262 | } 263 | } 264 | 265 | Function SetVirtualFolderColumns { 266 | If ($SetVirtualFolders -eq 1 -And $SetVirtualFolderColumns -eq 1) { 267 | Explorer 'C:\' 268 | Start-Sleep 1 269 | & $CloseExpW 270 | Start-Sleep 1 271 | Remove-Item $T1 2>$Null 272 | & $RegExe Export $Bag2 $T1 /y 2>$Null 273 | 274 | If (-Not(Test-Path -Path $T1)) { 275 | & $RegExe Export $Bag1 $T1 /y 276 | $Data = Get-Content $T1 | Out-String 277 | $Data = $Data.Replace('\Bags\1\Shell\', '\Bags\AllFolders\Shell\') 278 | } 279 | Else { 280 | $Data = Get-Content $T1 | Out-String 281 | $Data = $Data.Replace('\Bags\2\Shell\', '\Bags\AllFolders\Shell\') 282 | } 283 | 284 | Out-File -InputObject $Data -encoding Unicode -filepath $T1 285 | & $RegExe Import $T1 /reg:64 286 | 287 | $Data = $Data.Replace('\Bags\AllFolders\Shell\', '\Bags\AllFolders\ComDlg\') 288 | Out-File -InputObject $Data -encoding Unicode -filepath $T1 289 | & $RegExe Import $T1 /reg:64 290 | 291 | $Data = $Data.Replace('\Bags\AllFolders\ComDlg\', '\Bags\AllFolders\ComDlgLegacy\') 292 | Out-File -InputObject $Data -encoding Unicode -filepath $T1 293 | & $RegExe Import $T1 /reg:64 294 | } 295 | } 296 | 297 | Function RestartExplorer { 298 | & $RegExe Import $ShellBak 2>$Null 299 | & $RegExe Import $DeskBak 2>$Null 300 | & $RegExe Import $TBarBak 2>$Null 301 | & $RegExe Add $BwgM /v NodeSlots /d '02' /t REG_BINARY /f >$Null 302 | & $RegExe Add $BwgM /v NodeSlot /d 1 /t REG_DWORD /f >$Null 303 | If ($WinVer -ne '7') {ResetStoreAppViews} 304 | Stop-Process -Force -ErrorAction SilentlyContinue -ProcessName Explorer 305 | If ($ResetThumbs -eq 1) {ResetThumbCache} 306 | Explorer $PSScriptRoot 307 | Exit 308 | } 309 | 310 | Function DeleteUserKeys { 311 | & $RegExe Delete $BwgM /f 2>$Null 312 | & $RegExe Delete $Bwgs /f 2>$Null 313 | & $RegExe Delete $BagM /f 2>$Null 314 | & $RegExe Delete $Bags /f 2>$Null 315 | & $RegExe Delete $CUFT /f 2>$Null 316 | & $RegExe Delete $Defs /f 2>$Null 317 | } 318 | 319 | $Restore = ($FileExt -eq '.reg') 320 | 321 | If ($Restore) { 322 | Write-Host `n'Restore from backup...'`n 323 | } 324 | Else { 325 | 326 | $iniContent = Get-IniContent $File 327 | $Reset = $iniContent['Options']['Reset'] 328 | $Backup = $iniContent['Options']['Backup'] 329 | $Generic = [Int]$iniContent['Options']['Generic'] 330 | $NoFolderThumbs = [Int]$iniContent['Options']['NoFolderThumbs'] 331 | $UnhideAppData = [Int]$iniContent['Options']['UnhideAppData'] 332 | $UnhidePublicDesktop = [Int]$iniContent['Options']['UnhidePublicDesktop'] 333 | $ClassicSearch = [Int]$iniContent['Options']['ClassicSearch'] 334 | $HomeGrouping = [Int]$iniContent['Options']['HomeGrouping'] 335 | $LibraryGrouping = [Int]$iniContent['Options']['LibraryGrouping'] 336 | $SearchOnly = [Int]$iniContent['Options']['SearchOnly'] 337 | $SetVirtualFolders = [Int]$iniContent['Options']['SetVirtualFolders'] 338 | $SetVirtualFolderColumns = [Int]$iniContent['Options']['SetVirtualFolderColumns'] 339 | $ThisPCoption = [Int]$iniContent['Options']['ThisPCoption'] 340 | $ThisPCView = [Int]$iniContent['Options']['ThisPCView'] 341 | $ThisPCNG = [Int]$iniContent['Options']['ThisPCNG'] 342 | $ApplyViews = ($iniContent['Options']['ApplyViews'] -eq 1) 343 | $ApplyOptions = ($iniContent['Options']['ApplyOptions'] -eq 1) 344 | 345 | If ($Reset -eq 1) { 346 | Write-Host `n'Reset to Windows defaults...'`n 347 | } 348 | Else { 349 | Write-Host `n'Setting Explorer folder views...'`n 350 | } 351 | } 352 | 353 | Function RemoveTempFiles { 354 | Remove-Item $T1 2>$Null 355 | Remove-Item $T2 2>$Null 356 | Remove-Item $T3 2>$Null 357 | Remove-Item $T4 2>$Null 358 | Remove-Item $T5 2>$Null 359 | Remove-Item $T6 2>$Null 360 | Remove-Item $T7 2>$Null 361 | } 362 | 363 | $LogoExists = $false 364 | Try { $LogoExists = (Get-ItemProperty -Path $ShPS -ErrorAction SilentlyContinue).logo -eq 'none' } Catch {} 365 | 366 | RemoveTempFiles 367 | 368 | If ($Backup -eq 1) { 369 | If (!(Test-Path -Path "$AppData\Backup")) {Mkdir "$AppData\Backup" >$Null} 370 | & $RegExe Export $BagM $T1 /y 2>$Null 371 | & $RegExe Export $Bags $T2 /y 2>$Null 372 | & $RegExe Export $Strm $T3 /y 2>$Null 373 | & $RegExe Export $CUFT $T4 /y 2>$Null 374 | & $RegExe Export $BwgM $T5 /y 2>$Null 375 | & $RegExe Export $Bwgs $T6 /y 2>$Null 376 | & $RegExe Export $Advn $T7 /y 2>$Null 377 | & $CmdExe /c Copy $T1+$T2+$T3+$T4+$T5+$T6+$T7 $BakFile >$Null 2>$Null 378 | RemoveTempFiles 379 | } 380 | 381 | If ($ApplyViews -Or $Restore) { 382 | 383 | # Backup current Desktop view details 384 | & $RegExe Export $Desk $DeskBak /y 2>$Null 385 | & $RegExe Export $TBar $TBarBak /y 2>$Null 386 | 387 | & $RegExe Delete $Desk /f 2>$Null 388 | Remove-Item $ShellBak 2>$Null 389 | Remove-Item -Path "$ShPS\*" -Recurse 2>$Null 390 | Remove-ItemProperty -Path "$ShPS" -Name Logo 2>$Null 391 | Remove-ItemProperty -Path "$ShPS" -Name FolderType 2>$Null 392 | Remove-ItemProperty -Path "$ShPS" -Name SniffedFolderType 2>$Null 393 | & $RegExe Export $Shel $ShellBak /y 2>$Null 394 | 395 | # Clear current Explorer view registry values 396 | 397 | DeleteUserKeys 398 | 399 | # Restore from backup, restart Explorer, exit 400 | 401 | If ($Restore) { 402 | & $RegExe Import $File 403 | RestartExplorer 404 | } 405 | } 406 | 407 | If ($ApplyOptions) { 408 | 409 | # Enable/disable show of file extensions 410 | 411 | $ShowExt = [Int]$iniContent['Options']['ShowExt'] 412 | & $RegExe Add $Advn /v HideFileExt /t REG_DWORD /d (1-$ShowExt) /f 413 | 414 | # Enable/disable compact view in Windows 11 415 | 416 | If ($CurBld -ge 21996) { 417 | $CompView = [Int]$iniContent['Options']['CompView'] 418 | & $RegExe Add $Advn /v UseCompactMode /t REG_DWORD /d ($CompView) /f 419 | } 420 | 421 | # Enable/disable show hidden files and folders 422 | 423 | $ShowHidden = [Int]$iniContent['Options']['ShowHidden'] 424 | & $RegExe Add $Advn /v Hidden /t REG_DWORD /d (2-$ShowHidden) /f 425 | 426 | # Enable/disable classic context menu in Windows 11 427 | 428 | If ($CurBld -ge 21996) { 429 | $ClassicContextMenu = [Int]$iniContent['Options']['ClassicContextMenu'] 430 | If ($ClassicContextMenu -eq 1) {& $RegExe Add "$Clcm\InprocServer32" /reg:64 /f 2>$Null} 431 | Else {& $RegExe Delete $Clcm /reg:64 /f 2>$Null} 432 | } 433 | 434 | # Enable/disable Copy and Move items in context menu 435 | 436 | $CopyMoveInMenu = [Int]$iniContent['Options']['CopyMoveInMenu'] 437 | If ($CopyMoveInMenu -eq 1) { 438 | & $RegExe Add $CCMH /reg:64 /f 2>$Null 439 | & $RegExe Add $MCMH /reg:64 /f 2>$Null 440 | } 441 | Else { 442 | & $RegExe Delete $CCMH /reg:64 /f 2>$Null 443 | & $RegExe Delete $MCMH /reg:64 /f 2>$Null 444 | } 445 | 446 | # Enable/disable Internet in Windows search 447 | 448 | $NoSearchInternet = [Int]$iniContent['Options']['NoSearchInternet'] 449 | $NoSearchHighlights = [Int]$iniContent['Options']['NoSearchHighlights'] 450 | If (($NoSearchInternet -eq 0) -or ($NoSearchHighlights -eq 0)) { 451 | & $RegExe Add $UPol /v DisableSearchBoxSuggestions /t REG_DWORD /d 0 /f 2>$Null 452 | } 453 | $NoSearchInternet = 1-$NoSearchInternet 454 | $NoSearchHighlights = 1-$NoSearchHighlights 455 | & $RegExe Add $Srch /v BingSearchEnabled /t REG_DWORD /d ($NoSearchInternet) /f 456 | & $RegExe Add $Srhl /v IsDynamicSearchBoxEnabled /t REG_DWORD /d ($NoSearchHighlights) /f 457 | & $RegExe Add $Srdc /v ShowDynamicContent /t REG_DWORD /d ($NoSearchHighlights) /f 458 | 459 | # Unhide/hide AppData folder 460 | 461 | If ($UnhideAppData -eq 1) {& $CmdExe /c attrib -h "$UAppData"} 462 | Else {& $CmdExe /c attrib +h "$UAppData"} 463 | 464 | # Enable/disable classic search 465 | # Only applicable if "new" search is enabled 466 | # If "new" search is disabled, then you get classic search 467 | 468 | If (($CurBld -ge 18363) -And ($CurBld -lt 21996)) { 469 | $Key = "HKCU\Software\Classes\CLSID\{1d64637d-31e9-4b06-9124-e83fb178ac6e}" 470 | If ($ClassicSearch -eq 1) {& $RegExe add "$Key\TreatAs" /ve /t REG_SZ /d "{64bc32b5-4eec-4de7-972d-bd8bd0324537}" /reg:64 /f 2>$Null} 471 | Else {& $RegExe delete $Key /reg:64 /f 2>$Null} 472 | } 473 | 474 | # Enable/disable numerical sort order (UAC) 475 | 476 | $NoNumericalSort = $iniContent['Options']['NoNumericalSort'] 477 | 478 | $CurVal = & $RegExe Query $PolE /v NoStrCmpLogical 2>$Null 479 | If ($CurVal.Length -eq 4) {$CurVal = $CurVal[2][-1]} Else {$CurVal = 0} 480 | 481 | If ($CurVal -ne $NoNumericalSort) { 482 | $NoNumericalSort = [int]$NoNumericalSort 483 | $C1 = "$CSRegExe Add $PolE /v NoStrCmpLogical /t REG_DWORD /d $NoNumericalSort /f" 484 | } 485 | 486 | $CurVal = & $RegExe Query $PolEM /v NoStrCmpLogical 2>$Null 487 | If ($CurVal.Length -eq 4) { 488 | $CurVal = $CurVal[2][-1] 489 | If ($CurVal -ne $NoNumericalSort) { 490 | $NoNumericalSort = [int]$NoNumericalSort 491 | $C1 = "$C1;$CSRegExe Add $PolEM /v NoStrCmpLogical /t REG_DWORD /d $NoNumericalSort /f" 492 | } 493 | } 494 | 495 | # Enable/disable Windows 10 "new" search (UAC) 496 | 497 | If (($CurBld -ge 19045) -And ($CurBld -lt 21996) -And ($UBR -ge 3754)) { 498 | 499 | $Win10Search = $iniContent['Options']['Win10Search'] 500 | 501 | $CurVal = & $ViveExe /query /id:18755234 502 | If ($CurVal[4] -Match 'Enabled') {$CurVal = '1'} Else {$CurVal = '0'} 503 | 504 | If ($CurVal -ne $Win10Search) { 505 | $Action = '/enable' 506 | If ($Win10Search -eq '0') {$Action = '/disable'} 507 | $C2 = "$ViveExe $Action /id:18755234" 508 | } 509 | } 510 | 511 | # Enable/disable Windows 11 App SDK Explorer (UAC) 512 | 513 | If (($CurBld -eq 22621) -And ($UBR -ge 3007) -And ($UBR -lt 3085)) { 514 | 515 | $Win11Explorer = $iniContent['Options']['Win11Explorer'] 516 | 517 | $CurVal = & $ViveExe /query /id:40729001 518 | If ($CurVal[4] -Match 'Disabled') {$CurVal = '1'} Else {$CurVal = '0'} 519 | 520 | If ($CurVal -ne $Win11Explorer) { 521 | $Action = '/enable' 522 | If ($Win11Explorer -eq '1') {$Action = '/disable'} 523 | $C3 = "$ViveExe $Action /id:40729001" 524 | } 525 | } 526 | 527 | # Enable/disable Windows 10 Explorer on Windows 11 528 | 529 | If ($CurBld -ge 21996) { 530 | 531 | $Win10Explorer = $iniContent['Options']['Win10Explorer'] 532 | 533 | If ($Win10Explorer -eq '1') { 534 | & $RegExe Add $E10A /ve /t REG_SZ /d "CLSID_ItemsViewAdapter" /reg:64 /f 535 | & $RegExe Add "$E10A\InProcServer32" /ve /t REG_SZ /d "C:\Windows\System32\Windows.UI.FileExplorer.dll_" /reg:64 /f 536 | & $RegExe Add "$E10A\InProcServer32" /v "ThreadingModel" /t REG_SZ /d "Apartment" /reg:64 /f 537 | & $RegExe Add $E10B /ve /t REG_SZ /d "File Explorer Xaml Island View Adapter" /reg:64 /f 538 | & $RegExe Add "$E10B\InProcServer32" /ve /t REG_SZ /d "C:\Windows\System32\Windows.UI.FileExplorer.dll_" /reg:64 /f 539 | & $RegExe Add "$E10B\InProcServer32" /v "ThreadingModel" /t REG_SZ /d "Apartment" /reg:64 /f 540 | 541 | # This binary value is required for the old Explorer to remember its window size and position 542 | & $RegExe Add "HKCU\Software\Microsoft\Internet Explorer\Toolbar\ShellBrowser" /f /v ITBar7Layout /t REG_BINARY /d 13000000000000000000000020000000100001000000000001000000010700005e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 543 | } 544 | Else { 545 | & $RegExe Delete $E10A /reg:64 /f 2>$Null 546 | & $RegExe Delete $E10B /reg:64 /f 2>$Null 547 | } 548 | } 549 | 550 | # Remove/Restore Home in Navigation pane (Windows 11) 551 | 552 | $RemoveHome = [Int]$iniContent['Options']['RemoveHome'] 553 | $Key = 'HKCU\Software\Classes\CLSID\{f874310e-b6b7-47dc-bc84-b9e6b38f5903}' 554 | & $RegExe Add $Key /v System.IsPinnedToNameSpaceTree /d (1-$RemoveHome) /t REG_DWORD /reg:64 /f 555 | 556 | # Remove/Restore Gallery in Navigation pane (Windows 11) 557 | 558 | $RemoveGallery = [Int]$iniContent['Options']['RemoveGallery'] 559 | $Key = 'HKCU\Software\Classes\CLSID\{e88865ea-0e1c-4e20-9aa6-edcd0212c87c}' 560 | & $RegExe Add $Key /v System.IsPinnedToNameSpaceTree /d (1-$RemoveGallery) /t REG_DWORD /reg:64 /f 561 | 562 | # Apply/remove Legacy Dialog Fix (UAC) 563 | 564 | If ($CurBld -ge 18363) { 565 | 566 | Try { 567 | $CurVal = & $RegExe Query $PolL /v Place1 2>$Null 568 | If ($CurVal.Length -eq 4) {$CurVal = '1'} Else {$CurVal = '0'} 569 | } 570 | Catch { 571 | $CurVal = '0' 572 | } 573 | 574 | $LegacyDialogFix = $iniContent['Options']['LegacyDialogFix'] 575 | 576 | $DesktopPlace = 'shell:::{3936E9E4-D92C-4EEE-A85A-BC16D5EA0819}' 577 | If (($CurBld -ge 22621) -And ($UBR -ge 3007)) { 578 | $DesktopPlace = 'shell:::{F874310E-B6B7-47DC-BC84-B9E6B38F5903}' 579 | } 580 | 581 | If ($CurVal -ne $LegacyDialogFix) { 582 | If ($LegacyDialogFix -eq '1') { 583 | $A = "$CSRegExe Add $PolL /v Place0 /t REG_SZ /d '$DesktopPlace' /f" 584 | $B = "$CSRegExe Add $PolL /v Place1 /t REG_SZ /d 'shell:ThisPCDesktopFolder' /f" 585 | $C = "$CSRegExe Add $PolL /v Place2 /t REG_SZ /d 'shell:Libraries' /f" 586 | $D = "$CSRegExe Add $PolL /v Place3 /t REG_SZ /d 'shell:MyComputerFolder' /f" 587 | $E = "$CSRegExe Add $PolL /v Place4 /t REG_SZ /d 'shell:NetworkPlacesFolder' /f" 588 | $C4 = "$A;$B;$C;$D;$E" 589 | } 590 | Else { 591 | $C4 = "$CSRegExe Delete $PolL /f" 2>$Null 592 | } 593 | } 594 | } 595 | 596 | # Unhide/hide Public Desktop folder 597 | 598 | $folderPath = "C:\Users\Public\Desktop" 599 | $folder = Get-Item -Path $folderPath -Force 600 | if ($folder.Attributes -band [System.IO.FileAttributes]::Hidden) { 601 | If ($UnhidePublicDesktop -eq 1) {$C5 = "$CmdExe /c attrib -h $folderPath"} 602 | } else { 603 | If ($UnhidePublicDesktop -eq 0) {$C5 = "$CmdExe /c attrib +h $folderPath"} 604 | } 605 | 606 | # Execute commands that require UAC elevation 607 | 608 | $Cmd = "$C1$C2$C3$C4$C5" 609 | If ($Cmd -ne '') { 610 | $Cmd = "$C1;$C2;$C3;$C4;$C5" 611 | Try { 612 | Start-Process -WindowStyle Hidden -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command $Cmd" -Verb RunAs 2>$Null 613 | } 614 | Catch { 615 | } 616 | } 617 | 618 | # Enable/disable "Let's finish setting up", "Welcome experience", and "Tips and tricks" 619 | 620 | $NoSuggestions = [Int]$iniContent['Options']['NoSuggestions'] 621 | $NoSuggestions = 1-$NoSuggestions 622 | & $RegExe Add $Lets /v ScoobeSystemSettingEnabled /t REG_DWORD /d ($NoSuggestions) /f 623 | & $RegExe Add $remd /v SubscribedContent-310093Enabled /t REG_DWORD /d ($NoSuggestions) /f 624 | & $RegExe Add $remd /v SubscribedContent-338389Enabled /t REG_DWORD /d ($NoSuggestions) /f 625 | 626 | # Set Explorer Start Folder 627 | 628 | & $RegExe Delete $ESTR /reg:64 /f 2>$Null 629 | $ExplorerStart = [Int]$iniContent['Options']['ExplorerStart'] 630 | If ($ExplorerStart -eq 1) { 631 | $ExplorerStartOption = [Int]$iniContent['Options']['ExplorerStartOption'] 632 | If ($ExplorerStartOption -eq 4) { 633 | $ExplorerStartPath = 'explorer ' + $iniContent['Options']['ExplorerStartPath'] 634 | $ExplorerStartPath = $ExplorerStartPath -Replace '\\$', '\\' 635 | & $RegExe Add $ESTC /ve /t REG_SZ /d $ExplorerStartPath /reg:64 /f 636 | & $RegExe Add $ESTC /v DelegateExecute /t REG_SZ /reg:64 /f 637 | } 638 | Else { 639 | & $RegExe Add $Advn /v LaunchTo /t REG_DWORD /d ($ExplorerStartOption) /f 640 | } 641 | } 642 | } 643 | 644 | # If reset, restart Explorer and exit 645 | 646 | If ($Reset -eq 1) { 647 | & $RegExe Delete $Strm /f 2>$Null 648 | RestartExplorer 649 | } 650 | 651 | # Function to help Set up views for This PC 652 | 653 | Function SetBagValues ($Key) { 654 | & $RegExe Add $Key /v FFlags /d 0x41200001 /t REG_DWORD /f >$Null 655 | & $RegExe Add $Key /v LogicalViewMode /d $LVMode /t REG_DWORD /f >$Null 656 | & $RegExe Add $Key /v Mode /d $Mode /t REG_DWORD /f >$Null 657 | $Group = 1-$ThisPCNG 658 | & $RegExe Add $Key /v GroupView /d $Group /t REG_DWORD /f >$Null 659 | & $RegExe Add $Key /v IconSize /d $IconSize /t REG_DWORD /f >$Null 660 | & $RegExe Add $Key /v 'GroupByKey:FMTID' /d '{B725F130-47EF-101A-A5F1-02608C9EEBAC}' /t REG_SZ /f >$Null 661 | & $RegExe Add $Key /v 'GroupByKey:PID' /d 4 /t REG_DWORD /f >$Null 662 | } 663 | 664 | # Set view values based on selection index 665 | 666 | Function SetViewValues($Index) { 667 | If ($Index -eq 1) {$Script:LVMode = 1; $Script:Mode = 4; $Script:IconSize = 16} 668 | If ($Index -eq 2) {$Script:LVMode = 4; $Script:Mode = 3; $Script:IconSize = 16} 669 | If ($Index -eq 3) {$Script:LVMode = 2; $Script:Mode = 6; $Script:IconSize = 48} 670 | If ($Index -eq 4) {$Script:LVMode = 5; $Script:Mode = 8; $Script:IconSize = 32} 671 | If ($Index -eq 5) {$Script:LVMode = 3; $Script:Mode = 1; $Script:IconSize = 16} 672 | If ($Index -eq 6) {$Script:LVMode = 3; $Script:Mode = 1; $Script:IconSize = 48} 673 | If ($Index -eq 7) {$Script:LVMode = 3; $Script:Mode = 1; $Script:IconSize = 96} 674 | If ($Index -eq 8) {$Script:LVMode = 3; $Script:Mode = 1; $Script:IconSize = 256} 675 | } 676 | 677 | Function BuildRegData($Key) { 678 | $Script:RegData += $Script:ImpR + "$Key\$GUID]`r`n" 679 | $Script:RegData += '@="' + $Script:FT + '"' + "`r`n" 680 | $Script:RegData += '"Mode"=dword:' + $Script:Mode + "`r`n" 681 | If ($Key -eq 'Shell') { 682 | $AutoArrange = [Int]$iniContent['Options']['AutoArrange'] * 1 683 | $AlignToGrid = [Int]$iniContent['Options']['AlignToGrid'] * 4 684 | $LastDigit = $AutoArrange + $AlignToGrid 685 | $Script:RegData += '"FFlags"=dword:4300000' + $LastDigit + "`r`n" 686 | Return 687 | } 688 | $Script:RegData += '"LogicalViewMode"=dword:' + $Script:LVMode + "`r`n" 689 | If ($Script:LVMode -eq 3) {$Script:RegData += '"IconSize"=dword:' + '{0:x}' -f $Script:IconSize + "`r`n"} 690 | $Group = 1-$FileDialogNG 691 | $Script:RegData += '"GroupView"=dword:' + $Group + "`r`n" 692 | } 693 | 694 | If ($ApplyViews) { 695 | 696 | # Enable/disable folder thumbnails 697 | 698 | If ($NoFolderThumbs -eq 1) { 699 | $ResetThumbs = !$LogoExists 700 | & $RegExe Add $Shel /v Logo /d none /t REG_SZ /f 701 | } 702 | Else { 703 | & $RegExe Delete $Shel /v Logo /f 2>$Null 704 | $ResetThumbs = $LogoExists 705 | } 706 | 707 | # Enable/Disable full row select (requires legacy spacing) 708 | 709 | $LegacySpacing = [Int]$iniContent['Options']['LegacySpacing'] 710 | $NoFullRowSelect = 0 711 | If ($LegacySpacing -eq 1) { 712 | $NoFullRowSelect = [Int]$iniContent['Options']['NoFullRowSelect'] 713 | & $RegExe Add $Advn /v FullRowSelect /t REG_DWORD /d (1-$NoFullRowSelect) /f 714 | } 715 | $SystemTextColor = $iniContent['Options']['SystemTextColor'] 716 | & $RegExe Add 'HKCU\Control Panel\Colors' /v WindowText /t REG_SZ /d $SystemTextColor /f 717 | 718 | # The FolderTypes key does not include entries for This PC 719 | # This PC does not have a unique GUID so we'll set it's view via a Bags entry: 720 | 721 | If ($ThisPCoption -ne 0) { 722 | & $RegExe Add $BagM /v NodeSlots /d '02' /t REG_BINARY /f 723 | & $RegExe Add $BagM /v MRUListEx /d '00000000ffffffff' /t REG_BINARY /f >$Null 724 | & $RegExe Add $BagM /v '0' /d '14001F50E04FD020EA3A6910A2D808002B30309D0000' /t REG_BINARY /f >$Null 725 | & $RegExe Add "$BagM\0" /v NodeSlot /d 1 /t REG_DWORD /f >$Null 726 | $CustomIconSize = $iniContent['Generic']['IconSize'] 727 | SetViewValues($ThisPCView) 728 | If ($CustomIconSize -ne '') {$IconSize = $CustomIconSize} 729 | $GUID = '{5C4F28B5-F869-4E84-8E60-F11DB97C5CC7}' 730 | SetBagValues("$Bags\1\ComDlg\$GUID") 731 | SetBagValues("$Bags\1\Shell\$GUID") 732 | } 733 | 734 | If ($Generic -eq 1) {& $RegExe Add $Shel /v FolderType /d Generic /t REG_SZ /f} 735 | 736 | If ($SetVirtualFolders -eq 1) { 737 | $GUID = $iniContent['Generic']['GUID'] 738 | $GroupBy = $iniContent['Generic']['GroupBy'] 739 | $CustomIconSize = $iniContent['Generic']['IconSize'] 740 | SetViewValues([Int]$iniContent['Generic']['View']) 741 | If ($CustomIconSize -ne '') {$IconSize = $CustomIconSize} 742 | & $RegExe Add "$Bags\AllFolders\Shell\$GUID" /v FFlags /d '0x41200001' /t REG_DWORD /f 743 | & $RegExe Add "$Bags\AllFolders\Shell\$GUID" /v Mode /d "$Mode" /t REG_DWORD /f 744 | & $RegExe Add "$Bags\AllFolders\Shell\$GUID" /v LogicalViewMode /d "$LVMode" /t REG_DWORD /f 745 | If ($LVMode -eq 3) {& $RegExe Add "$Bags\AllFolders\Shell\$GUID" /v IconSize /d "$IconSize" /t REG_DWORD /f} 746 | If ($GroupBy -eq '') {& $RegExe Add "$Bags\AllFolders\Shell\$GUID" /v GroupView /d 0 /t REG_DWORD /f} 747 | } 748 | 749 | # Set Explorer folder view defaults: 750 | # 1) Export HKLM FolderTypes key 751 | # 2) Import FolderTypes key to HKCU 752 | # 2) Update HKCU FolderTypes default settings 753 | # 4) Restart Explorer 754 | # Note: Explorer will use HKCU key instead of HKLM key automatically 755 | 756 | # Copy FolderType key from HKLM to HKCU by exporting and importing 757 | 758 | & $RegExe Export $LMFT $RegFile1 /y 759 | $Data = Get-Content $RegFile1 760 | $Data = $Data -Replace 'HKEY_LOCAL_MACHINE','HKEY_CURRENT_USER' 761 | Out-File -InputObject $Data -encoding Unicode -filepath $RegFile1 762 | & $RegExe Import $RegFile1 /reg:64 763 | 764 | $FolderTypes = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes' 765 | 766 | # Create lookup table for path type properties so these can be excluded from 767 | # non-search views if the search-only option is enabled 768 | 769 | $PathItems = @{ 770 | 'ItemFolderPathDisplay' = '' 771 | 'ItemFolderPathDisplayNarrow' = '' 772 | 'ItemPathDisplay' = '' 773 | 'ItemFolderNameDisplay' = '' 774 | } 775 | 776 | $RegData = '' 777 | 778 | Get-ChildItem $FolderTypes | Get-ItemProperty | ForEach { 779 | 780 | $FT = $_.CanonicalName 781 | If ($iniContent.ContainsKey($FT)) { 782 | $Include = [Int]$iniContent[$FT]['Include'] 783 | 784 | If ($Include -eq 1) { 785 | 786 | $FileDialogOption = [Int]$iniContent[$FT]['FileDialogOption'] 787 | $FileDialogView = [Int]$iniContent[$FT]['FileDialogView'] 788 | $FileDialogNG = [Int]$iniContent[$FT]['FileDialogNG'] 789 | 790 | $GUID = $iniContent[$FT]['GUID'] 791 | 792 | $View = $iniContent[$FT]['View'] 793 | If ($FileDialogOption -ne 1) {$FileDialogView = $View} 794 | 795 | If (($FileDialogOption -eq 1 -And $FT -ne 'Global') -Or ($SetVirtualFolders -eq 1 -And $GUID -eq '{5C4F28B5-F869-4E84-8E60-F11DB97C5CC7}')) { 796 | SetViewValues($FileDialogView) 797 | BuildRegData('ComDlg') 798 | BuildRegData('ComDlgLegacy') 799 | } 800 | 801 | SetViewValues($View) 802 | 803 | If ($LegacySpacing -eq 1) { 804 | BuildRegData('Shell') 805 | } 806 | 807 | $GroupBy = $iniContent[$FT]['GroupBy'] 808 | $GroupByOrder = $iniContent[$FT]['GroupByOrder'] 809 | If (($FT -eq 'HomeFolder') -And ($HomeGrouping -eq 0)) { 810 | $GroupBy = 'Home.Grouping' 811 | $GroupByOrder = '+' 812 | } 813 | If (($FT.IndexOf('Library') -gt 0) -And ($LibraryGrouping -eq 0)) { 814 | $GroupBy = 'ItemSearchLocation' 815 | $GroupByOrder = '+' 816 | } 817 | If ($GroupBy -ne '') {$GroupBy = "System.$GroupBy"} 818 | $GroupBy = AdjustPrefix($GroupBy) 819 | If ($GroupByOrder -eq '+') {$GroupByOrder = 1} Else {$GroupByOrder = 0} 820 | 821 | #Code added June 2023 to disable Sort 4 822 | $SortBy = $iniContent[$FT]['SortBy'] 823 | If ($SortBy.Split(';').Count -eq 4) { 824 | $SortBy = $SortBy.SubString(0,$SortBy.LastIndexOf(';')) 825 | } 826 | $SortBy = 'prop:' + $SortBy 827 | $SortBy = $SortBy -Replace '\+','+System.' 828 | $SortBy = $SortBy -Replace '-','-System.' 829 | $SortBy = AdjustPrefix($SortBy) 830 | 831 | $CustomIconSize = $iniContent[$FT]['IconSize'] 832 | If ($CustomIconSize -ne '') {$IconSize = $CustomIconSize} 833 | $INIColumnList = $iniContent[$FT]['ColumnList'] 834 | $ArrColumnList = $INIColumnList.Split(';') 835 | $ColumnList = 'prop:' 836 | 837 | For($i=0; $i -lt $ArrColumnList.Count; $i++) { 838 | $ArrColumnListItem = $ArrColumnList[$i].Split(',') 839 | $Property = $ArrColumnListItem[2] 840 | If (($FT -Match 'Search') -Or (-Not ((($SearchOnly -eq 1) -And ($PathItems.ContainsKey($Property))) -Or ($Property -eq 'Search.Rank')))) { 841 | $Show = $ArrColumnListItem[0] 842 | $Width = ''; If ($ArrColumnListItem[1] -ne '') {$Width = '(' + $ArrColumnListItem[1] + ')'} 843 | $Property = 'System.' + $ArrColumnListItem[2] 844 | $Property = AdjustPrefix($Property) 845 | $ColumnList = "$ColumnList$Show$Width$Property;" 846 | } 847 | } 848 | $ColumnList = $ColumnList.Trim(';') 849 | $Key = $_.PSPath 850 | $Key = "$Key\TopViews" 851 | If (Test-Path -Path $Key) { 852 | Get-ChildItem $Key | Get-ItemProperty | ForEach { 853 | $GUID = $_.PSChildName 854 | $ChildKey = $Key + '\' + $GUID 855 | Set-ItemProperty -Path $ChildKey -Name 'LogicalViewMode' -Value $LVMode 856 | Set-ItemProperty -Path $ChildKey -Name 'IconSize' -Value $IconSize 857 | Set-ItemProperty -Path $ChildKey -Name 'GroupBy' -Value $GroupBy 858 | Set-ItemProperty -Path $ChildKey -Name 'GroupAscending' -Value $GroupByOrder 859 | Set-ItemProperty -Path $ChildKey -Name 'SortByList' -Value $SortBy 860 | Set-ItemProperty -Path $ChildKey -Name 'ColumnList' -Value $ColumnList 861 | } 862 | } 863 | } 864 | } 865 | } 866 | 867 | # Export results for use with comparison tools such as WinMerge 868 | 869 | & $RegExe Export $CUFT $RegFile2 /y 870 | 871 | # Import Reg data to force dialog views 872 | # This is MUCH faster than creating the keys using PowerShell 873 | 874 | If ($RegData -ne '') { 875 | $RegData = "Windows Registry Editor Version 5.00`r`n`r`n" + $RegData 876 | Out-File -InputObject $RegData -filepath $T1 877 | & $RegExe Import $T1 878 | } 879 | } 880 | 881 | # Replicate General Item view to AllFolders reg key 882 | SetVirtualFolderColumns 883 | 884 | # Import Reg data for any custom settings 885 | 886 | If (Test-Path -Path $Custom) {& $RegExe Import $Custom /reg:64} 887 | 888 | RestartExplorer -------------------------------------------------------------------------------- /src/313/seguiemj.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesFerch/WinSetView/aee13bade40bed1db46cd640e2d6ea03524addd3/src/313/seguiemj.eot --------------------------------------------------------------------------------