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

1089 lines
64 KiB

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", new[] { new MenuItem("Divehi Phonetic", "0465:00000465"), new MenuItem("Divehi Typewriter", "0465:00010465") }), new MenuItem("Dutch", "0413:00000413"), new MenuItem("Dzongkha", "0C51:00000C51"), new MenuItem("Estonian", "0425:00000425"), new MenuItem("Faeroese", "0438:00000438"), new MenuItem("Finnish", new[] { new MenuItem("Finnish", "040b:0000040b"), new MenuItem("Finnish with Sami", "040b:0001083b") }), new MenuItem("Futhark", "0407:00120c00"), new MenuItem("Georgian", new[] { new MenuItem("Georgian", "0437:00020437"), new MenuItem("Georgian (Ergonomic)", "0437:00020437"), new MenuItem("Georgian (QWERTY)", "0437:00010437"), new MenuItem("Georgian Ministry of Education and Science Schools", "0437:00030437"), new MenuItem("Georgian (Old Alphabets)", "0437:00030437") }), new MenuItem("German", new[] { new MenuItem("German", "0407:00000407"), new MenuItem("German (IBM)", "0407:00010407") }), new MenuItem("Gothic", "0407:000c0c00"), new MenuItem("Greek", new[] { new MenuItem("Greek", "0408:00000408"), new MenuItem("Greek (220)", "0408:00010408"), new MenuItem("Greek (220) Latin", "0408:00030408"), new MenuItem("Greek (319)", "0408:00020408"), new MenuItem("Greek (319) Latin", "0408:00040408"), new MenuItem("Greek Latin", "0408:00050408"), new MenuItem("Greek Polytonic", "0408:00600408") }), new MenuItem("Greenlandic", "046f:0000046f"), new MenuItem("Guarani", "0474:00000474"), new MenuItem("Gujarati", "0447:00000447"), new MenuItem("Hausa", "0468:00000468"), new MenuItem("Hebrew", "040d:0000040d"), new MenuItem("Hungarian", new[] { new MenuItem("Hungarian", "040e:0000040e"), new MenuItem("Hungarian 101-key", "040e:0001040e") }), new MenuItem("Icelandic", "040f:0000040f"), new MenuItem("Igbo", "0470:00000470"), new MenuItem("Indian", "4009:00004009"), new MenuItem("Inuktitut", new[] { new MenuItem("Inuktitut - Latin", "085d:0000085d"), new MenuItem("Inuktitut - Naqittaut", "085d:0001045d") }), new MenuItem("Irish", "083C:000001809"), new MenuItem("Italian", new[] { new MenuItem("Italian", "0410:00000410"), new MenuItem("Italian (142)", "0410:00010410") }), new MenuItem("Japanese NON-FUNCTIONAL", "0411:{03B5835F-F03C-411B-9CE2-AA23E1171E36}{A76C93D9-5523-4E90-AAFA-4DB112F9AC76}"), new MenuItem("Javanese", "0421:00110c00"), new MenuItem("Kannada", "044b:0000044b"), new MenuItem("Kazakh", "043f:0000043f"), new MenuItem("Khmer", new[] { new MenuItem("Khmer", "0453:00000453"), new MenuItem("Khmer (NIDA)", "0453:00010453") }), new MenuItem("Konkoni (Devanagari) - INSCRIPT", "0457:00000439"), new MenuItem("Korean", new[] { new MenuItem("Korean (Hangul)", "0412:{A028AE76-01B1-46C2-99C4-ACD9858AE02F}{B5FE1F02-D5F2-4445-9C03-C568F23C99A1}"), new MenuItem("Korean (Old Hangul)", "0412:{a1e2b86b-924a-4d43-80f6-8a820df7190f}{b60af051-257a-46bc-b9d3-84dad819bafb}") }), new MenuItem("Kyrgyz Cyrillic", "0440:00000440"), new MenuItem("Lao", "0454:00000454"), new MenuItem("Latin American", "080a:0000080a"), new MenuItem("Latvian", new[] { new MenuItem("Latvian (Standard)", "0426:00020426"), new MenuItem("Latvian (Legacy)", "0426:00010426") }), new MenuItem("Lisu", new[] { new MenuItem("Lisu (Basic)", "0409:00070c00"), new MenuItem("Lisu (Standard)", "0409:00080c00") }), new MenuItem("Lithuanian", new[] { new MenuItem("Lithuanian", "0427:00010427"), new MenuItem("Lithuanian IBM", "0427:00000427"), new MenuItem("Lithuanian Standard", "0427:00020427") }), new MenuItem("Luxembourgish", "046e:0000046e"), new MenuItem("Macedonia", new[] { new MenuItem("Macedonian (FYROM)", "042f:0000042f"), new MenuItem("Macedonian (FYROM) - Standard", "042f:0001042f") }), new MenuItem("Malayalam", "044c:0000044c"), new MenuItem("Maltese", new[] { new MenuItem("Maltese 47-key", "043a:0000043a"), new MenuItem("Maltese 48-key", "043a:0001043a") }), new MenuItem("Maori", "0481:00000481"), new MenuItem("Marathi", "044e:0000044e"), new MenuItem("Mongolian", new[] { new MenuItem("Mongoloian (Mongolian Script - Legacy)", "0850:00000850"), new MenuItem("Mongolian (Mongolian Script - Standard)", "0850:00020850"), new MenuItem("Mongolian Cyrillic", "0850:00000450") }), new MenuItem("Myanmar", "0455:00010c00"), new MenuItem("N'ko", "0409:000090c00"), new MenuItem("Nepali", "0461:00000461"), new MenuItem("New Tai Lue", "0409:00020c00"), new MenuItem("Norwegian", new[] { new MenuItem("Norwegian", "0814:00000414"), new MenuItem("Norwegian with Sami", "0814:0000043b") }), new MenuItem("Odia", "0448:00000448"), new MenuItem("Ol Chiki", "0409:d0c00"), new MenuItem("Old Italic", "0409:000f0c00"), new MenuItem("Osmanya", "0409:000e0c00"), new MenuItem("Pashto (Afghanistan)", "0463:00000463"), new MenuItem("Persian", new[] { new MenuItem("Persian", "0429:00000429"), new MenuItem("Persian (Standard)", "0429:00050429") }), new MenuItem("Phags-pa", "0409:000a0c00"), new MenuItem("Polish", new[] { new MenuItem("Polish (214)", "0415:00010415"), new MenuItem("Polish (Programmers)", "0415:00000415") }), new MenuItem("Punjabi", "0446:00000446"), new MenuItem("Romanian", new[] { new MenuItem("Romanian (Legacy)", "0418:00000418"), new MenuItem("Romanian (Programmers)", "0418:00020418"), new MenuItem("Romanian (Standard)", "0418:00010418") }), new MenuItem("Sakha", "0485:00000485"), new MenuItem("Sami", new[] { new MenuItem("Sami Extended Finland-Sweden", "083b:0002083b"), new MenuItem("Sami Extended Norway", "043b:0001043b") }), new MenuItem("Scottish Gaelic", "0809:00011809"), new MenuItem("Serbian", new[] { new MenuItem("Serbian (Cyrillic)", "1C1A:00000c1a"), new MenuItem("Serbian (Latin)", "241A:0000081a") }), new MenuItem("Sesotho sa Leboa", "046c:0000046c"), new MenuItem("Setswana", "0432:00000432"), new MenuItem("Sinhala", new[] { new MenuItem("Sinhala", "045b:0000045b"), new MenuItem("Sinhala - wij 9", "045b:0001045b") }), new MenuItem("Slovak", new[] { new MenuItem("Slovak", "041b:0000041b"), new MenuItem("Slovak (QWERTY)", "041b:0001041b") }), new MenuItem("Slovenian", "0424:00000424"), new MenuItem("Sora", "0409:00100c00"), new MenuItem("Sorbian", new[] { new MenuItem("Sorbian Extended", "042e:0001042e"), new MenuItem("Sorbian Standard", "042e:0002042e"), new MenuItem("Sorbian Standard (Legacy)", "042e:0000042e") }), new MenuItem("Swedish", new[] { new MenuItem("Swedish", "041d:0000041d"), new MenuItem("Swedish with Sami", "083b:0000083b") }), new MenuItem("Swiss", new[] { new MenuItem("Swiss French", "100c:0000100c"), new MenuItem("Swiss German", "0807:00000807") }), new MenuItem("Syriac", new[] { new MenuItem("Syriac", "045a:0000045a"), new MenuItem("Syriac Phonetic", "045a:0001045a") }), new MenuItem("Tai Le", "0409:00030c00"), new MenuItem("Tajik", "0428:00000428"), new MenuItem("Tamil", new[] { new MenuItem("Tamil", "0449:00000449"), new MenuItem("Tamil (99 Keyboard)", "0449:00020449") }), new MenuItem("Tatar", new[] { new MenuItem("Tatar", "0444:00010444"), new MenuItem("Tatar (Legacy)", "0444:00000444") }), new MenuItem("Telugu", "044a:0000044a"), new MenuItem("Thai", new[] { new MenuItem("Thai Kedmanee", "041e:0000041e"), new MenuItem("Thai Kedmanee (non-ShiftLock)", "041e:0002041e"), new MenuItem("Thai Pattachote", "041e:0001041e"), new MenuItem("Thai Pattachote (non-ShiftLock)", "041e:0003041e") }), new MenuItem("Tibetan", new[] { new MenuItem("Tibetan (PRC - Standard)", "0451:00010451"), new MenuItem("Tibetan (PRC - Legacy)", "0451:00000451") }), new MenuItem("Tifinagh", new[] { new MenuItem("Tifinagh (Basic)", "0409:00050c00"), new MenuItem("Tifinagh (Full)", "0409:00050c00") }), new MenuItem("Tigrinya", "0473:{E429B25A-E5D3-4D1F-9BE3-0C608477E3A1}{3CAB88B7-CC3E-46A6-9765-B772AD7761FF}"), new MenuItem("Turkish", new[] { new MenuItem("Turkish F", "041f:0001041f"), new MenuItem("Turkish Q", "041f:0000041f") }), new MenuItem("Turkmen", "0442:00000442"), new MenuItem("Uyghur", new[] { new MenuItem("Uyghur", "0480:00010480"), new MenuItem("Uygher (Legacy)", "0480:00000480"), new MenuItem("Uyghur (Greek 220)", "0480:00010408") }), new MenuItem("Ukrainian", new[] { new MenuItem("Ukrainian", "0422:00000422"), new MenuItem("Ukrainian (Enhanced)", "0422:00020422") }), new MenuItem("United Kingdom", new[] { new MenuItem("United Kingdom", "0809:00000809"), new MenuItem("United Kingdom Extended", "0809:00000452") }), new MenuItem("Urdu", "0420:00000420"), new MenuItem("Uzbek", "0843:00000843"), new MenuItem("Vietnamese", new[] { new MenuItem("Vietnamese", "042a:0000042a"), new MenuItem("Vietnamese Telex", "042A:{C2CB2CF0-AF47-413E-9780-8BC3A3C16068}{5FB02EC5-0A77-4684-B4FA-DEF8A2195628}") }), new MenuItem("Wolof", "0488:00000488"), new MenuItem("Yakut", "0485:00000485"), new MenuItem("Yoruba", "046a:0000056a"), };
}
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;
}
}
}