|
|
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Globalization;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading;
- using Ameliorated.ConsoleUtils;
- using Microsoft.Dism;
- using Microsoft.Win32;
- using static Ameliorated.ConsoleUtils.Menu;
-
- namespace amecs.Actions
- {
- public class Languages
- {
- public static bool ShowMenu()
- {
- while (true)
- {
- Program.Frame.Clear();
-
- var mainMenu = new Ameliorated.ConsoleUtils.Menu()
- {
- Choices =
- {
- true
- ? new Menu.MenuItem("Change Display Language", new Func<bool>(ShowDisplayMenu))
- {
- IsEnabled = false,
- SecondaryText = "[Not Supported]",
- SecondaryTextForeground = ConsoleColor.Red,
- PrimaryTextForeground = ConsoleColor.DarkGray
- }
- : new Menu.MenuItem("Change Display Language", new Func<bool>(ShowDisplayMenu)),
- new Menu.MenuItem("Add Keyboard Language", new Func<bool>(ShowAddKeyboardLanguageMenu)),
- new Menu.MenuItem("Remove Keyboard Language", new Func<bool>(ShowRemoveKeyboardLanguageMenu)),
- Globals.WinVer >= 22000
- ? new Menu.MenuItem("Install Language Pack", new Func<bool>(ShowLanguagePackMenu))
- {
- IsEnabled = false,
- SecondaryText = "[Not Supported]",
- SecondaryTextForeground = ConsoleColor.Red,
- PrimaryTextForeground = ConsoleColor.DarkGray
- }
- : new Menu.MenuItem("Install Language Pack", new Func<bool>(ShowLanguagePackMenu)),
- Globals.WinVer >= 22000
- ? new Menu.MenuItem("Uninstall Language Pack", new Func<bool>(ShowRemoveLanguagePackMenu))
- {
- IsEnabled = false,
- SecondaryText = "[Not Supported]",
- SecondaryTextForeground = ConsoleColor.Red,
- PrimaryTextForeground = ConsoleColor.DarkGray
- }
- : new Menu.MenuItem("Uninstall Language Pack", new Func<bool>(ShowRemoveLanguagePackMenu)),
- Menu.MenuItem.Blank,
- new Menu.MenuItem("Return to Menu", null),
- new Menu.MenuItem("Exit", new Func<bool>(Globals.Exit))
- },
- SelectionForeground = ConsoleColor.Green
- };
-
- Func<bool> result;
- try
- {
- mainMenu.Write();
- var res = mainMenu.Load();
- if (res == null)
- return true;
- result = (Func<bool>)res;
- } catch (Exception e)
- {
- Console.WriteLine(e);
- Console.ReadLine();
- return false;
- }
-
- try
- {
- result.Invoke();
- } catch (Exception e)
- {
- ConsoleTUI.ShowErrorBox("Error while loading a menu: " + e.ToString(), null);
- }
- }
- }
-
- private static bool ShowDisplayMenu() => ShowLanguageMenu(true);
- private static bool ShowLanguagePackMenu() => ShowLanguageMenu(false);
- private static List<string> currentLanguagePacks;
-
- public static bool ShowLanguageMenu(bool display)
- {
- /*
- if (display)
- {
- try
- {
- var deskKey = Registry.Users.OpenSubKey(Globals.UserSID + "\\Control Panel\\Desktop");
- var pendingLang = ((string[])deskKey.GetValue("PreferredUILanguagesPending")).First();
-
- ConsoleTUI.OpenFrame.WriteCentered("Checking languages");
- var indicator = new ConsoleUtils.LoadingIndicator(true);
- Thread.Sleep(50);
- indicator.Dispose();
-
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("A language change is currently pending.\r\nYou must restart before continuing.", ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- } catch {}
- }
- */
-
- List<MenuItem> displayItems = new List<MenuItem>(LanguagePackItems);
- if (!display)
- {
- DismApi.Initialize(DismLogLevel.LogErrors);
- DismPackageCollection packages;
- using (var session = DismApi.OpenOnlineSession())
- {
- packages = DismApi.GetPackages(session);
- session.Close();
- }
-
- DismApi.Shutdown();
- currentLanguagePacks = new List<string>(packages.Where(x => x.PackageName.StartsWith("Microsoft-Windows-Client-LanguagePack-Package")).Select(x => x.PackageName));
- }
-
- foreach (var menuItem in new List<MenuItem>(displayItems))
- {
- var tag = ((string)menuItem.ReturnValue).Split('|').First();
-
- string activeLang = null;
- string pendingLang = null;
- try
- {
- var deskKey = Registry.Users.OpenSubKey(Globals.UserSID + "\\Control Panel\\Desktop");
- activeLang = ((string[])deskKey.GetValue("PreferredUILanguages")).First();
- pendingLang = ((string[])deskKey.GetValue("PreferredUILanguagesPending")).First();
- } catch
- {
- }
-
- if (display && tag == pendingLang && activeLang != pendingLang)
- {
- var clone = menuItem.Clone();
- clone.IsEnabled = false;
- clone.PrimaryTextForeground = ConsoleColor.DarkGray;
- clone.SecondaryText = "[Pending Restart]";
- clone.SecondaryTextForeground = ConsoleColor.Yellow;
- displayItems.ReplaceItem(menuItem, clone);
- }
-
- if (display && tag == activeLang && (activeLang == pendingLang || pendingLang == null))
- {
- var clone = menuItem.Clone();
- clone.IsEnabled = false;
- clone.PrimaryTextForeground = ConsoleColor.DarkGray;
- clone.SecondaryText = "[Current]";
- clone.SecondaryTextForeground = ConsoleColor.Yellow;
- displayItems.ReplaceItem(menuItem, clone);
- }
-
- if (!display)
- {
- if (currentLanguagePacks.Any(x => x.Contains('~' + tag + '~')))
- {
- var clone = menuItem.Clone();
- clone.IsEnabled = false;
- clone.PrimaryTextForeground = ConsoleColor.DarkGray;
- clone.SecondaryText = "[Installed]";
- clone.SecondaryTextForeground = ConsoleColor.Yellow;
- displayItems.ReplaceItem(menuItem, clone);
- }
- }
- }
-
-
- var result = amecs.ShowDefaultMenu(displayItems.ToList());
- if (result.GetType().Name.StartsWith("Func")) return ((Func<bool>)result).Invoke();
- var languageTag = ((string)result).Split('|').First();
- var downloadAmount = int.Parse(((string)result).Split('|').Last(), CultureInfo.InvariantCulture);
- if (!display)
- {
- return InstallLanguagePack(downloadAmount, languageTag);
- }
- else
- {
- return ChangeDisplayLanguage(downloadAmount, languageTag);
- }
- }
-
- private static List<string> CurrentLanguages;
-
- public static bool ShowAddKeyboardLanguageMenu()
- {
- while (true)
- {
- CurrentLanguages = new List<string>();
- try
- {
- var langsKey = Registry.Users.OpenSubKey(Globals.UserSID + "\\Control Panel\\International\\User Profile");
- foreach (var langKey in langsKey.GetSubKeyNames())
- {
- CurrentLanguages.AddRange(langsKey.OpenSubKey(langKey).GetValueNames().Where(x => x.Contains(':')));
- }
- } catch
- {
- }
-
- List<MenuItem> displayItems = new List<MenuItem>(KeyboardLanguageItems);
- foreach (var menuItem in displayItems.Where(x => x.ReturnValue.GetType().Name == "String").ToList())
- {
- if (CurrentLanguages.Contains((string)menuItem.ReturnValue, StringComparer.InvariantCultureIgnoreCase))
- {
- var clone = menuItem.Clone();
- clone.IsEnabled = false;
- clone.PrimaryTextForeground = ConsoleColor.DarkGray;
- clone.SecondaryText = "[Installed]";
- clone.SecondaryTextForeground = ConsoleColor.Yellow;
- displayItems.ReplaceItem(menuItem, clone);
- }
- }
-
- var result = amecs.ShowDefaultMenu(displayItems);
- if (result.GetType().Name.StartsWith("Func")) return ((Func<bool>)result).Invoke();
- if (result.GetType().Name == "String")
- {
- return AddKeyboardLanguage((string)result);
- }
- else
- {
- var subDisplayItems = ((MenuItem[])result).ToList();
- foreach (var menuItem in subDisplayItems)
- {
- if (CurrentLanguages.Contains((string)menuItem.ReturnValue, StringComparer.InvariantCultureIgnoreCase))
- {
- menuItem.IsEnabled = false;
- menuItem.PrimaryTextForeground = ConsoleColor.DarkGray;
- menuItem.SecondaryText = "[Installed]";
- menuItem.SecondaryTextForeground = ConsoleColor.Yellow;
- }
- else
- {
- menuItem.IsEnabled = true;
- menuItem.PrimaryTextForeground = null;
- menuItem.SecondaryText = null;
- menuItem.SecondaryTextForeground = null;
- }
- }
-
- var subResult = amecs.ShowDefaultMenu(subDisplayItems);
- if (subResult.GetType().Name.StartsWith("Func"))
- {
- ((Func<bool>)subResult).Invoke();
- continue;
- }
-
- return AddKeyboardLanguage((string)subResult);
- }
- }
- }
-
- public static bool AddKeyboardLanguage(string tip)
- {
- var choice = new ChoicePrompt()
- {
- Text = "Make default keyboard language? (Y/N): "
- }.Start();
- if (!choice.HasValue) return true;
- bool makeDefault = choice == 0;
- try
- {
- ConsoleTUI.OpenFrame.WriteCentered("\r\nAdding keyboard language");
- using (new ConsoleUtils.LoadingIndicator(true))
- {
- var result = NSudo.RunProcessAsUser(NSudo.GetUserToken(), "PowerShell.exe", makeDefault ? $"-NoP -C \"$List=Get-WinUserLanguageList;" + $"$List[0].InputMethodTips.Add('{tip}');" + $"Set-WinUserLanguageList $List -Force;" + $"Set-WinDefaultInputMethodOverride -InputTip '{tip}'\"" : $"-NoP -C \"$List=Get-WinUserLanguageList;" + $"$List[0].InputMethodTips.Add('{tip}');" + $"Set-WinUserLanguageList $List -Force\"");
- if (result == null)
- {
- throw new Exception("Could not start user PowerShell process.");
- }
-
- if (result > 0)
- {
- throw new Exception("PowerShell exited with a non-zero exitcode.");
- }
- }
- } catch (Exception e)
- {
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
-
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close($"Keyboard language added successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return true;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct COORD
- {
- public short X;
- public short Y;
-
- public COORD(short X, short Y)
- {
- this.X = X;
- this.Y = Y;
- }
- };
-
- [DllImport("kernel32.dll", SetLastError = true)]
- internal static extern bool WriteConsoleOutputCharacter(IntPtr hConsoleOutput, StringBuilder lpCharacter, uint nLength, COORD dwWriteCoord, out uint lpNumberOfCharsWritten);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- static extern IntPtr GetStdHandle(int nStdHandle);
-
- private static bool InstallLanguagePack(int downloadAmount, string language) => InstallLanguage(downloadAmount, language, true);
-
- private static bool InstallLanguage(int downloadAmount, string language, bool finalize)
- {
- var downloadFolder = Directory.Exists(Path.Combine(Globals.UserFolder, "Desktop")) ? Path.Combine(Globals.UserFolder, "Desktop") : Environment.GetEnvironmentVariable("TEMP");
- var file = "LangPacks-" + new Random().Next(0, 9999);
- try
- {
- try
- {
- DriveInfo drive = DriveInfo.GetDrives().First(x => x.Name == Environment.GetEnvironmentVariable("SYSTEMDRIVE") + "\\");
- if (drive.AvailableFreeSpace < downloadAmount * 2.3)
- {
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("There is not enough available space on the system drive.", ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
- } catch { }
-
- string amountString = "0";
- if (downloadAmount == 2480000) amountString = "2.5";
- if (downloadAmount == 2900000) amountString = "2.9";
- if (downloadAmount == 3230000) amountString = "3.2";
- var choice = new ChoicePrompt()
- {
- Text = $"A ~{amountString}GB Language Packs ISO must be downloaded\r\nContinue? (Y/N): "
- }.Start();
- if (choice == null || choice == 1) return false;
- if (!amecs.IsInternetAvailable())
- {
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("An internet connection is required for this action.", ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
-
- var sevenZip = ExistsInPath("7z.exe");
- sevenZip = sevenZip == null ? File.Exists(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES%\7-Zip\7z.exe")) ? Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES%\7-Zip\7z.exe") : null : sevenZip;
- var choco = ExistsInPath("choco.exe");
- choco = choco == null ? File.Exists(Environment.ExpandEnvironmentVariables(@"%PROGRAMDATA%\chocolatey\choco.exe")) ? Environment.ExpandEnvironmentVariables(@"%PROGRAMDATA%\chocolatey\choco.exe") : null : choco;
-
- if (String.IsNullOrEmpty(sevenZip) && String.IsNullOrEmpty(choco))
- {
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("7zip or Chocolatey must be installed for this action.", ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
-
- bool wasMissing = false;
- if (String.IsNullOrEmpty(sevenZip))
- {
- wasMissing = true;
- ConsoleTUI.OpenFrame.WriteCentered("\r\nInstalling 7zip");
- using (new ConsoleUtils.LoadingIndicator(true))
- {
- var proc = new Process();
- var startInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
- WindowStyle = ProcessWindowStyle.Normal,
- Arguments = "install -y --force --allow-empty-checksums 7zip",
- FileName = choco,
- };
- proc.StartInfo = startInfo;
- proc.Start();
- proc.WaitForExit();
- }
-
- sevenZip = ExistsInPath("7z.exe");
- sevenZip = sevenZip == null ? File.Exists(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES%\7-Zip\7z.exe")) ? Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES%\7-Zip\7z.exe") : null : sevenZip;
-
- if (sevenZip == null)
- {
- ConsoleTUI.OpenFrame.WriteCentered("\r\nUninstalling 7zip");
- using (new ConsoleUtils.LoadingIndicator(true))
- {
- var proc = new Process();
- var startInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
- WindowStyle = ProcessWindowStyle.Normal,
- Arguments = "uninstall 7zip -y --force-dependencies --allow-empty-checksums",
- FileName = choco,
- };
- proc.StartInfo = startInfo;
- proc.Start();
- proc.WaitForExit();
- }
-
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("Could not detect 7zip.", ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
- }
-
- try
- {
- ConsoleTUI.OpenFrame.WriteCenteredLine("\r\nDownload progress");
- using (WebClientEx wc = new WebClientEx(0, (long)downloadAmount * 1000))
- {
- var stdout = GetStdHandle(-11);
- var maxHashTags = (ConsoleTUI.OpenFrame.DisplayWidth - 5);
- wc.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e)
- {
- var currentHashTags = (int)Math.Ceiling(Math.Min(((double)e.ProgressPercentage / 100) * maxHashTags, maxHashTags));
- var spaces = maxHashTags - currentHashTags + (4 - e.ProgressPercentage.ToString().Length);
- var sb = new StringBuilder(new string('#', currentHashTags) + new string(' ', spaces) + e.ProgressPercentage + "%");
- uint throwaway;
- WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)Console.CursorTop), out throwaway);
- };
- var task = wc.DownloadFileTaskAsync(new Uri("https://software-download.microsoft.com/download/pr/19041.1.191206-1406.vb_release_CLIENTLANGPACKDVD_OEM_MULTI.iso"), Path.Combine(downloadFolder, file + ".ISO"));
- task.Wait();
- Thread.Sleep(100);
- var sb = new StringBuilder(new string('#', maxHashTags) + " 100%");
- uint throwaway;
- WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)Console.CursorTop), out throwaway);
- }
-
- ConsoleTUI.OpenFrame.WriteCentered("\r\n\r\nExtracting ISO");
- using (new ConsoleUtils.LoadingIndicator(true))
- {
- var proc = new Process();
- var startInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
- WindowStyle = ProcessWindowStyle.Normal,
- Arguments = $@"e -y -o""{Path.Combine(downloadFolder, file)}"" ""{Path.Combine(downloadFolder, file + ".ISO")}"" x64\langpacks\*.cab",
- FileName = sevenZip,
- };
- proc.StartInfo = startInfo;
- proc.Start();
- proc.WaitForExit();
- }
-
- try
- {
- File.Delete(Path.Combine(downloadFolder, file + ".ISO"));
- } catch
- {
- }
- } catch (Exception e)
- {
- try
- {
- if (wasMissing)
- {
- ConsoleTUI.OpenFrame.WriteCentered("\r\nUninstalling 7zip");
- using (new ConsoleUtils.LoadingIndicator(true))
- {
- var proc = new Process();
- var startInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
- WindowStyle = ProcessWindowStyle.Normal,
- Arguments = "uninstall 7zip -y --force-dependencies --allow-empty-checksums",
- FileName = choco,
- };
- proc.StartInfo = startInfo;
- proc.Start();
- proc.WaitForExit();
- }
- }
- } catch
- {
- }
-
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
-
- if (wasMissing)
- {
- ConsoleTUI.OpenFrame.WriteCentered("\r\nUninstalling 7zip");
- using (new ConsoleUtils.LoadingIndicator(true))
- {
- var proc = new Process();
- var startInfo = new ProcessStartInfo
- {
- CreateNoWindow = true,
- UseShellExecute = false,
- WindowStyle = ProcessWindowStyle.Normal,
- Arguments = "uninstall 7zip -y --force-dependencies --allow-empty-checksums",
- FileName = choco,
- };
- proc.StartInfo = startInfo;
- proc.Start();
- proc.WaitForExit();
- }
- }
-
- var cab = Path.Combine(downloadFolder, file, $"Microsoft-Windows-Client-Language-Pack_x64_{language}.cab");
- if (!File.Exists(cab))
- {
- try
- {
- Directory.Delete(Path.Combine(downloadFolder, file));
- } catch
- {
- }
-
- throw new Exception("Extraction failed.");
- }
-
- ConsoleTUI.OpenFrame.WriteCentered("\r\nInstalling language pack");
- var topCache = Console.CursorTop;
- var leftCache = Console.CursorLeft;
- Console.WriteLine();
- bool inProgress = false;
- try
- {
- using (var indicator = new ConsoleUtils.LoadingIndicator(true))
- {
- DismApi.Initialize(DismLogLevel.LogErrors);
- using (var session = DismApi.OpenOnlineSession())
- {
- var stdout = GetStdHandle(-11);
- bool indicatorStopped = false;
- var maxHashTags = (ConsoleTUI.OpenFrame.DisplayWidth - 5);
- DismApi.AddPackage(session, cab, false, true, delegate(DismProgress progress)
- {
- inProgress = true;
- if (!indicatorStopped)
- {
- indicator.Stop();
- Console.SetCursorPosition(leftCache, topCache);
- Console.WriteLine(" ");
- }
-
- indicatorStopped = true;
- var progressPerc = progress.Current / 10;
- var currentHashTags = (int)Math.Ceiling(Math.Min(((double)progressPerc / 100) * maxHashTags, maxHashTags));
- var spaces = maxHashTags - currentHashTags + (4 - progressPerc.ToString().Length);
- var sb = new StringBuilder(new string('#', currentHashTags) + new string(' ', spaces) + progressPerc + "%");
- uint throwaway;
- WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)topCache), out throwaway);
- inProgress = false;
- });
- session.Close();
- Thread.Sleep(100);
- var sb = new StringBuilder(new string('#', maxHashTags) + " 100%");
- uint throwaway;
- WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)topCache), out throwaway);
- }
-
- DismApi.Shutdown();
- }
- } catch (Exception e)
- {
- while (inProgress)
- {
- Thread.Sleep(50);
- }
-
- try
- {
- Directory.Delete(Path.Combine(downloadFolder, file), true);
- } catch
- {
- }
-
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("DISM error: " + e.Message, ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
-
- Directory.Delete(Path.Combine(downloadFolder, file), true);
- } catch (Exception e)
- {
- try
- {
- Directory.Delete(Path.Combine(downloadFolder, file), true);
- } catch
- {
- }
-
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
-
- if (finalize)
- {
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("Language pack installed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- }
-
- return true;
- }
-
- public static string ExistsInPath(string fileName)
- {
- if (File.Exists(fileName)) return fileName;
- var values = Environment.GetEnvironmentVariable("PATH");
- foreach (var path in values.Split(Path.PathSeparator).Where(x => !x.Contains("chocolatey\\bin")))
- {
- var fullPath = Path.Combine(path, fileName);
- if (File.Exists(fullPath)) return fullPath;
- if (!fileName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) && File.Exists(fullPath + ".exe")) return fullPath + ".exe";
- }
-
- return null;
- }
-
- public static bool ShowRemoveKeyboardLanguageMenu()
- {
- CurrentLanguages = new List<string>();
- try
- {
- var langsKey = Registry.Users.OpenSubKey(Globals.UserSID + "\\Control Panel\\International\\User Profile");
- foreach (var langKey in langsKey.GetSubKeyNames())
- {
- CurrentLanguages.AddRange(langsKey.OpenSubKey(langKey).GetValueNames().Where(x => x.Contains(':')));
- }
- } catch
- {
- throw new Exception("Could not fetch installed keyboard languages.\r\n");
- }
-
- List<MenuItem> displayItems = new List<MenuItem>();
- foreach (var menuItem in KeyboardLanguageItems.Where(x => x.ReturnValue.GetType().Name == "String"))
- {
- if (CurrentLanguages.Contains((string)menuItem.ReturnValue, StringComparer.InvariantCultureIgnoreCase))
- {
- displayItems.Add(menuItem);
- }
- }
-
- foreach (var menuItemList in KeyboardLanguageItems.Where(x => x.ReturnValue.GetType().Name != "String").Select(x => x.ReturnValue))
- {
- var subDisplayItems = ((MenuItem[])menuItemList).ToList();
-
- foreach (var subMenuItem in subDisplayItems)
- {
- if (CurrentLanguages.Contains((string)subMenuItem.ReturnValue, StringComparer.InvariantCultureIgnoreCase))
- {
- displayItems.Add(subMenuItem);
- }
- }
- }
-
- var result = amecs.ShowDefaultMenu(displayItems);
- if (result.GetType().Name.StartsWith("Func")) return ((Func<bool>)result).Invoke();
- return RemoveKeyboardLanguage((string)result);
- }
-
- private static bool RemoveKeyboardLanguage(string language)
- {
- ConsoleTUI.OpenFrame.WriteCentered("Removing keyboard language");
- try
- {
- using (new ConsoleUtils.LoadingIndicator(true))
- {
- StringBuilder reAddCommand = new StringBuilder("");
- foreach (var tag in CurrentLanguages.Where(x => !x.Equals(language, StringComparison.InvariantCultureIgnoreCase)))
- {
- reAddCommand.Append($@";$List[0].InputMethodTips.Add('{tag}')");
- }
-
- var result = NSudo.RunProcessAsUser(NSudo.GetUserToken(),
- "PowerShell.exe", $"-NoP -C \"$Tag=(Get-WinUserLanguageList)[0].LanguageTag;" +
- $"$List = New-WinUserLanguageList $Tag" +
- $"{reAddCommand.ToString()};" +
- $"Set-WinUserLanguageList $List -Force\"");
- if (result == null)
- {
- throw new Exception("Could not start user PowerShell process.");
- }
-
- if (result > 0)
- {
- throw new Exception("PowerShell exited with a non-zero exitcode.");
- }
- }
- } catch (Exception e)
- {
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
-
- CurrentLanguages = new List<string>();
- var langsKey = Registry.Users.OpenSubKey(Globals.UserSID + "\\Control Panel\\International\\User Profile");
- foreach (var langKey in langsKey.GetSubKeyNames())
- {
- CurrentLanguages.AddRange(langsKey.OpenSubKey(langKey).GetValueNames().Where(x => x.Contains(':')));
- }
-
- if (CurrentLanguages.Contains(language, StringComparer.InvariantCultureIgnoreCase))
- {
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("Keyboard language could not be removed. If it is the\r\nactive UI language, this is normal.", ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
-
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("Keyboard language removed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return true;
- }
-
- public static bool ShowRemoveLanguagePackMenu()
- {
- DismApi.Initialize(DismLogLevel.LogErrors);
- DismPackageCollection packages;
- using (var session = DismApi.OpenOnlineSession())
- {
- packages = DismApi.GetPackages(session);
- session.Close();
- }
-
- DismApi.Shutdown();
- currentLanguagePacks = new List<string>(packages.Where(x => x.PackageName.StartsWith("Microsoft-Windows-Client-LanguagePack-Package")).Select(x => x.PackageName));
- List<MenuItem> displayItems = new List<MenuItem>();
- foreach (var menuItem in LanguagePackItems)
- {
- var tag = ((string)menuItem.ReturnValue).Split('|').First();
- var pkg = currentLanguagePacks.FirstOrDefault(x => x.Contains('~' + tag + '~'));
- if (pkg != null)
- {
- var clone = menuItem.Clone();
-
- string activeLang = null;
- try
- {
- var deskKey = Registry.Users.OpenSubKey(Globals.UserSID + "\\Control Panel\\Desktop");
- activeLang = ((string[])deskKey.GetValue("PreferredUILanguages")).First();
- } catch
- {
- }
-
- if (activeLang == tag)
- {
- clone.IsEnabled = false;
- clone.PrimaryTextForeground = ConsoleColor.DarkGray;
- clone.SecondaryText = "[UI Language]";
- clone.SecondaryTextForeground = ConsoleColor.Yellow;
- }
-
- clone.ReturnValue = pkg;
- displayItems.Add(clone);
- }
- }
-
- var result = amecs.ShowDefaultMenu(displayItems.ToList());
- if (result.GetType().Name.StartsWith("Func")) return ((Func<bool>)result).Invoke();
- return RemoveLanguagePack((string)result);
- }
-
- private static bool RemoveLanguagePack(string package)
- {
- ConsoleTUI.OpenFrame.WriteCentered("Removing language pack");
- var topCache = Console.CursorTop;
- var leftCache = Console.CursorLeft;
- bool inProgress = false;
- try
- {
- using (var indicator = new ConsoleUtils.LoadingIndicator(true))
- {
- DismApi.Initialize(DismLogLevel.LogErrors);
- using (var session = DismApi.OpenOnlineSession())
- {
- var stdout = GetStdHandle(-11);
- bool indicatorStopped = false;
- var maxHashTags = (ConsoleTUI.OpenFrame.DisplayWidth - 5);
- DismApi.RemovePackageByName(session, package, delegate(DismProgress progress)
- {
- inProgress = true;
- if (!indicatorStopped)
- {
- indicator.Stop();
- Console.SetCursorPosition(leftCache, topCache);
- Console.WriteLine(" ");
- }
-
- indicatorStopped = true;
- var progressPerc = progress.Current / 10;
- var currentHashTags = (int)Math.Ceiling(Math.Min(((double)progressPerc / 100) * maxHashTags, maxHashTags));
- var spaces = maxHashTags - currentHashTags + (4 - progressPerc.ToString().Length);
- var sb = new StringBuilder(new string('#', currentHashTags) + new string(' ', spaces) + progressPerc + "%");
- uint throwaway;
- WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)Console.CursorTop), out throwaway);
- inProgress = false;
- });
- session.Close();
- Thread.Sleep(100);
- var sb = new StringBuilder(new string('#', maxHashTags) + " 100%");
- uint throwaway;
- WriteConsoleOutputCharacter(stdout, sb, (uint)sb.Length, new COORD((short)ConsoleTUI.OpenFrame.DisplayOffset, (short)Console.CursorTop), out throwaway);
- }
-
- DismApi.Shutdown();
- }
- } catch (Exception e)
- {
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("DISM error: " + e.Message, ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
-
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("Language pack removed successfully", ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return true;
- }
-
- public static bool ChangeDisplayLanguage(int downloadAmount, string language)
- {
- DismApi.Initialize(DismLogLevel.LogErrors);
- DismPackageCollection packages;
- using (var session = DismApi.OpenOnlineSession())
- {
- packages = DismApi.GetPackages(session);
- session.Close();
- }
-
- DismApi.Shutdown();
- currentLanguagePacks = new List<string>(packages.Where(x => x.PackageName.StartsWith("Microsoft-Windows-Client-LanguagePack-Package")).Select(x => x.PackageName));
-
- if (!currentLanguagePacks.Any(x => x.Contains('~' + language + '~')))
- {
- if (!InstallLanguage(downloadAmount, language, false))
- return false;
-
- ConsoleTUI.OpenFrame.WriteLine();
- ConsoleTUI.OpenFrame.WriteLine();
- }
-
- var choice = new ChoicePrompt()
- {
- Text = "Make default keyboard language? (Y/N): "
- }.Start();
- if (!choice.HasValue) return true;
- bool makeDefault = choice == 0;
-
- string previousDefault = null;
- if (!makeDefault)
- {
- try
- {
- var langsKey = Registry.Users.OpenSubKey(Globals.UserSID + "\\Control Panel\\International\\User Profile");
-
- try { previousDefault = (string)langsKey.GetValue("InputMethodOverride");} catch {}
-
- if (previousDefault == null)
- {
- string activeLang = null;
- try
- {
- var deskKey = Registry.Users.OpenSubKey(Globals.UserSID + "\\Control Panel\\Desktop");
- activeLang = ((string[])deskKey.GetValue("PreferredUILanguages")).First();
- } catch
- {
- }
-
- var keyName = langsKey.GetSubKeyNames().FirstOrDefault(x => x == activeLang);
- if (keyName == null) keyName = langsKey.GetSubKeyNames().FirstOrDefault(x => x.StartsWith(activeLang.Split('-').First()));
- var langKey = langsKey.OpenSubKey(keyName);
-
- foreach (var langValue in langKey.GetValueNames().Where(x => x.Contains(':')))
- {
- if ((int)langKey.GetValue(langValue) == 1)
- previousDefault = langValue;
- }
- }
- } catch (Exception e) {
- }
- }
-
-
- CurrentLanguages = new List<string>();
- try
- {
- var langsKey = Registry.Users.OpenSubKey(Globals.UserSID + "\\Control Panel\\International\\User Profile");
- foreach (var langKey in langsKey.GetSubKeyNames())
- {
- CurrentLanguages.AddRange(langsKey.OpenSubKey(langKey).GetValueNames().Where(x => x.Contains(':')));
- }
- } catch
- {
- }
-
- ConsoleTUI.OpenFrame.WriteCentered("\r\nSetting language");
- try
- {
- using (new ConsoleUtils.LoadingIndicator(true))
- {
- try
- {
- Process proc = new Process();
- proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
- proc.StartInfo.FileName = "PowerShell.exe";
- proc.StartInfo.Arguments = $"-NoP -C \"Set-WinSystemLocale {language}\"";
- proc.Start();
- proc.WaitForExit();
- } catch { }
-
- StringBuilder reAddCommand = new StringBuilder("");
- foreach (var tag in CurrentLanguages)
- {
- reAddCommand.Append($@";$List[0].InputMethodTips.Add('{tag}')");
- }
-
- var result = NSudo.RunProcessAsUser(NSudo.GetUserToken(),
- "PowerShell.exe", previousDefault == null
- ? $"-NoP -C \"$List = New-WinUserLanguageList {language}" +
- $"{reAddCommand.ToString()};" +
- $"Set-WinUserLanguageList $List -Force;" +
- $"Set-WinDefaultInputMethodOverride\""
- : $"-NoP -C \"$List = New-WinUserLanguageList {language}" +
- $"{reAddCommand.ToString()};" +
- $"Set-WinUserLanguageList $List -Force;" +
- $"Set-WinDefaultInputMethodOverride '{previousDefault}'\""
- );
- if (result == null)
- {
- throw new Exception("Could not start user PowerShell process.");
- }
-
- if (result > 0)
- {
- throw new Exception("PowerShell exited with a non-zero exitcode.");
- }
-
- new Reg.Value() { KeyName = "HKU\\" + Globals.UserSID + "\\Control Panel\\Desktop", ValueName = "PreferredUILanguagesPending", Data = new[] { language }, Type = Reg.RegistryValueType.REG_MULTI_SZ }.Apply();
- }
- } catch (Exception e)
- {
- Console.WriteLine();
- ConsoleTUI.OpenFrame.Close("Error: " + e.Message.TrimEnd('\n').TrimEnd('\r'), ConsoleColor.Red, Console.BackgroundColor, new ChoicePrompt()
- {
- AnyKey = true,
- Text = "Press any key to return to the Menu: "
- });
- return false;
- }
-
- Console.WriteLine();
- if ((int?)ConsoleTUI.OpenFrame.Close("Display language changed to " + language, ConsoleColor.Green, Console.BackgroundColor, new ChoicePrompt()
- {
- TextForeground = ConsoleColor.Yellow,
- Text = "Restart to apply changes? (Y/N): "
- }) == 0) amecs.RestartWindows(false, true);
- return true;
- }
-
- private static readonly MenuItem[] LanguagePackItems = new[] { new MenuItem("Arabic (ar-SA)", "ar-SA|2480000"), new MenuItem("Bulgarian (bg-BG)", "bg-BG|2480000"), new MenuItem("Chineese [Simplified] (zh-CN)", "zh-CN|3230000"), new MenuItem("Chineese [Traditional] (zh-TW)", "zh-TW|3230000"), new MenuItem("Croatian (hr-HR)", "hr-HR|2900000"), new MenuItem("Czech (cs-CZ)", "cs-CZ|2480000"), new MenuItem("Danish (da-DK)", "da-DK|2480000"), new MenuItem("Dutch (nl-NL)", "nl-NL|2900000"), new MenuItem("English [US] (en-US)", "en-US|2480000"), new MenuItem("English [UK] (en-GB)", "en-GB|2480000"), new MenuItem("Estonian (et-EE)", "et-EE|2480000"), new MenuItem("Finnish (fi-FI)", "fi-FI|2480000"), new MenuItem("French [Canada] (fr-CA)", "fr-CA|2480000"), new MenuItem("French [France] (fr-FR)", "fr-FR|2900000"), new MenuItem("German (de-DE)", "de-DE|2480000"), new MenuItem("Greek (el-GR)", "el-GR|2480000"), new MenuItem("Hebrew (he-IL)", "he-IL|2900000"), new MenuItem("Hungarian (hu-HU)", "hu-HU|2900000"), new MenuItem("Italian (it-IT)", "it-IT|2900000"), new MenuItem("Japanese (ja-JP)", "ja-JP|2900000"), new MenuItem("Korean (ko-KR)", "ko-KR|2900000"), new MenuItem("Latvian (lv-LV)", "lv-LV|2900000"), new MenuItem("Lithuanian (lt-LT)", "lt-LT|2900000"), new MenuItem("Norwegian (nb-NO)", "nb-NO|2900000"), new MenuItem("Polish (pl-PL)", "pl-PL|3230000"), new MenuItem("Portugeese [Brazil] (pt-BR)", "pt-BR|3230000"), new MenuItem("Portugeese [Portugal] (pt-PT)", "pt-PT|3230000"), new MenuItem("Romanian (ro-RO)", "ro-RO|3230000"), new MenuItem("Russian (ru-RU)", "ru-RU|3230000"), new MenuItem("Serbian (sr-Latn-RS)", "tn-RS|3230000"), new MenuItem("Slovak (sk-SK)", "sk-SK|3230000"), new MenuItem("Slovenian (sl-SI)", "sl-SI|3230000"), new MenuItem("Spanish [Mexico] (es-MX)", "es-MX|2480000"), new MenuItem("Spanish [Spain] (es-ES)", "es-ES|2480000"), new MenuItem("Swedish (sv-SE)", "sv-SE|3230000"), new MenuItem("Thai (th-TH)", "th-TH|3230000"), new MenuItem("Turkish (tr-TR)", "tr-TR|3230000"), new MenuItem("Ukrainian (uk-UA)", "uk-UA|3230000"), };
- private static readonly MenuItem[] KeyboardLanguageItems = new[] { new MenuItem("United States", new[] { new MenuItem("United States - English", "0409:00000409"), new MenuItem("United States - International", "0409:00020409"), new MenuItem("United States - Dvorak", "0409:00010409"), new MenuItem("United States - Dvorak (Left Hand)", "0409:00030409"), new MenuItem("United States - Dvorak (Right Hand)", "0409:00040409") }), new MenuItem("Chinese", new[] { new MenuItem("Chineese (Simplified)", "0804:{81D4E9C9-1D3B-41BC-9E6C-4B40BF79E35E}{FA550B04-5AD7-411f-A5AC-CA038EC515D7}"), new MenuItem("Chineese (Traditional) NON-FUNCTIONAL", "0404:{B115690A-EA02-48D5-A231-E3578D2FDF80}{B2F9C502-1742-11D4-9790-0080C882687E}"), new MenuItem("Chineese (Traditional, Hong Kong S.A.R.)", "0404:00000c04"), new MenuItem("Chineese (Traditonal Macao S.A.R.)", "0404:00001404"), new MenuItem("Chineese (Simplified, Singapore)", "0404:00001004") }), new MenuItem("Hindi (Devanagari) Traditional", "0439:00010439"), new MenuItem("Spanish", new[] { new MenuItem("Spanish (Spain)", "0c0a:0000040a"), new MenuItem("Spanish (Mexico)", "080a:0000080a"), new MenuItem("Spanish Variation", "0c0a:0001040a") }), new MenuItem("French", "040c:0000040c"), new MenuItem("Arabic", new[] { new MenuItem("Arabic (101)", "0401:00000401"), new MenuItem("Arabic (102)", "0401:00010401"), new MenuItem("Arabic (102 AZERTY)", "0401:00020401") }), new MenuItem("Russian", new[] { new MenuItem("Russian", "0419:00000419"), new MenuItem("Russian - Mnemonic", "0419:00020419"), new MenuItem("Russian (Typewriter)", "0419:00010419") }), new MenuItem("Bangla", new[] { new MenuItem("Bangla (Bangladesh)", "0445:00000445"), new MenuItem("Bangla (India)", "0445:00020445"), new MenuItem("Bangla (India) - Legacy", "0445:00010445") }), new MenuItem("Portuguese", new[] { new MenuItem("Portuguese", "0816:00000816"), new MenuItem("Portuguese (Brazilian ABNT)", "0816:00000416"), new MenuItem("Portuguese (Brazilian ABNT2)", "0816:00010416") }), new MenuItem("Albanian", "041c:0000041c"), new MenuItem("Amharic", "045e:{E429B25A-E5D3-4D1F-9BE3-0C608477E3A1}{8F96574E-C86C-4bd6-9666-3F7327D4CBE8}"), new MenuItem("Armenian", new[] { new MenuItem("Armenian Eastern", "042b:0000042b"), new MenuItem("Armenian Phonetic", "042b:0002042b"), new MenuItem("Armenian Typewriter", "042b:0003042b"), new MenuItem("Armenian Western", "042b:0001042b") }), new MenuItem("Assamese - Inscript", "044d:0000044d"), new MenuItem("Azerbaijani", new[] { new MenuItem("Azerbaijani (Standard)", "042c:0001042c"), new MenuItem("Azerbaijani Cyrillic", "042c:0000082c"), new MenuItem("Azerbaijani Latin", "042c:0000042c") }), new MenuItem("Bashkir", "046d:0000046d"), new MenuItem("Belarusian", "0423:00000423"), new MenuItem("Belgian", new[] { new MenuItem("Belgian (Comma)", "080c:0001080c"), new MenuItem("Belgian (Period)", "080c:00000813"), new MenuItem("Belgian French", "080c:0000080c") }), new MenuItem("Bosnian (Cyrillic)", "141a:00000201a"), new MenuItem("Buginese", "0421:000b0c00"), new MenuItem("Bulgarian", new[] { new MenuItem("Bulgarian", "0402:00030402"), new MenuItem("Bulgarian Latin", "0402:00010402"), new MenuItem("Bulgarian (Phonetic Layout)", "0402:00020402"), new MenuItem("Bulgarian (Phonetic Traditonal)", "0402:00040402"), new MenuItem("Bulgarian (Typewriter)", "0402:00000402") }), new MenuItem("Canadian", new[] { new MenuItem("Canadian French", "0c0c:00001009"), new MenuItem("Canadian French (Legacy)", "0c0c:00000c0c"), new MenuItem("Canadian Multilingual Standard", "0c0c:00011009") }), new MenuItem("Central Atlas Tamazight", "085f:0000085f"), new MenuItem("Central Kurdish", "0429:00000429"), new MenuItem("Cherokee", new[] { new MenuItem("Cherokee Nation", "045c:0000045c"), new MenuItem("Cherokee Nation Phonetic", "045c:0001045c") }), new MenuItem("Croatian", "041a:0000041a"), new MenuItem("Czech", new[] { new MenuItem("Czech", "2000:00000405"), new MenuItem("Czech (QWERTY)", "2000:00010405"), new MenuItem("Czech Programmers", "2000:00020405") }), new MenuItem("Danish", "0406:00000406"), new MenuItem("Divehi", ne
- }
-
- public static class NativeMethods
- {
- private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
- private const uint FILE_READ_EA = 0x0008;
- private const uint FILE_FLAG_BACKUP_SEMANTICS = 0x2000000;
-
- [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
- static extern uint GetFinalPathNameByHandle(IntPtr hFile, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszFilePath, uint cchFilePath, uint dwFlags);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- static extern bool CloseHandle(IntPtr hObject);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPTStr)] string filename, [MarshalAs(UnmanagedType.U4)] uint access, [MarshalAs(UnmanagedType.U4)] FileShare share, IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
- [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, [MarshalAs(UnmanagedType.U4)] uint flagsAndAttributes, IntPtr templateFile);
-
- public static string GetFinalPathName(string path)
- {
- var h = CreateFile(path, FILE_READ_EA, FileShare.ReadWrite | FileShare.Delete, IntPtr.Zero, FileMode.Open, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);
- if (h == INVALID_HANDLE_VALUE) return null;
- try
- {
- var sb = new StringBuilder(1024);
- var res = GetFinalPathNameByHandle(h, sb, 1024, 0);
- if (res == 0) return null;
- return sb.ToString();
- } finally
- {
- CloseHandle(h);
- }
- }
- }
-
- public class WebClientEx : WebClient
- {
- private readonly long from;
- private readonly long to;
-
- public WebClientEx(long from, long to)
- {
- this.from = from;
- this.to = to;
- }
-
- protected override WebRequest GetWebRequest(Uri address)
- {
- var request = (HttpWebRequest)base.GetWebRequest(address);
- request.AddRange(this.from, this.to);
- return request;
- }
- }
- }
|