/// <summary> /// Sets the specified application compatibility layers for the specified /// executable file. /// </summary> /// <param name="path"> /// The path to the file to be configured. /// </param> /// <param name="compatLayers"> /// The compatibility layers. /// </param> /// <exception cref="ArgumentNullException"> /// path is null, empty or consists only of white-space characters. /// </exception> /// <exception cref="ArgumentInvalidException"> /// path is not a valid executable file. /// </exception> /// <exception cref="PathNotFoundException"> /// target does not exist. /// </exception> public static void SetLayers(string path, AppCompatLayers compatLayers) { if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentInvalidException(nameof(path)); } var file = PathEx.Combine(path); if (!File.Exists(file)) { throw new PathNotFoundException(file); } var type = PortableExecutable.GetMachineTypes(file); if (type != MachineType.AMD64 && type != MachineType.I386) { throw new ArgumentInvalidException(nameof(path)); } const string keyPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"; var builder = new StringBuilder(); var osVer = Environment.OSVersion.Version; if (compatLayers.DisableFullscreenOptimizations) { builder.AppendLine("DISABLEDXMAXIMIZEDWINDOWEDMODE"); } if (compatLayers.RunAsAdministrator) { builder.AppendLine("RUNASADMIN"); } if (compatLayers.RunIn640x480ScreenResolution) { builder.AppendLine("640x480"); } if (osVer.Major >= 10 && compatLayers.DpiScalingSystem != AppCompatDpiScalingSystem.Default) { builder.AppendLine(Enum.GetName(typeof(AppCompatDpiScalingSystem), compatLayers.DpiScalingSystem)?.ToUpperInvariant()); } if (osVer.Major >= 10 && compatLayers.DpiScalingBehavior != AppCompatDpiScalingBehavior.Default) { builder.AppendLine(Enum.GetName(typeof(AppCompatDpiScalingBehavior), compatLayers.DpiScalingBehavior)?.ToUpperInvariant()); } if (compatLayers.ColorMode != AppCompatColorMode.Default) { builder.AppendLine(Enum.GetName(typeof(AppCompatColorMode), compatLayers.ColorMode)?.ToUpperInvariant().TrimStart('_')); } if (compatLayers.OperatingSystem != AppCompatSystemVersion.Default) { var os = compatLayers.OperatingSystem; if (osVer.Major == 6) { if (osVer.Minor > 1) { if (os > AppCompatSystemVersion.Win7RTM) { os = AppCompatSystemVersion.VistaSP2; } } else { if (os > AppCompatSystemVersion.VistaSP2) { os = AppCompatSystemVersion.VistaSP2; } } } builder.AppendLine(Enum.GetName(typeof(AppCompatSystemVersion), os)?.ToUpperInvariant()); } var compatFlags = builder.ToString().Replace(Environment.NewLine, " ").Replace("_", " ").Trim(); if (string.IsNullOrEmpty(compatFlags)) { Reg.RemoveEntry(Registry.CurrentUser, keyPath, path); return; } Reg.Write(Registry.CurrentUser, keyPath, path, $"~ {compatFlags}"); }
private static bool PinUnpin(string path, bool pin) { if (string.IsNullOrWhiteSpace(path)) { return(false); } var file = PathEx.Combine(path); if (!File.Exists(file)) { return(false); } if (IsPinned(file) == pin) { return(true); } var isPresentWindows = Environment.OSVersion.Version.Major >= 10; var shellKeyPath = default(string); try { if (isPresentWindows) { //ProcessEx.CurrentPrincipal.ChangeName("explorer.exe"); throw new NotSupportedException(); } dynamic shell = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application")); var dir = shell.NameSpace(Path.GetDirectoryName(path)); var name = Path.GetFileName(path); var link = dir.ParseName(name); var verbs = link.Verbs(); var sb = new StringBuilder(byte.MaxValue); var lib = WinApi.NativeMethods.LoadLibrary(WinApi.DllNames.Shell32); _ = WinApi.NativeMethods.LoadString(lib, pin ? 0x150au : 0x150bu, sb, 0xff); var verb = sb.ToStringThenClear(); /* * if (!isPresentWindows) * { */ var applied = false; for (var i = 0; i < verbs.Count(); i++) { var e = verbs.Item(i); if ((pin || !e.Name.ContainsEx(verb)) && (!pin || !e.Name.EqualsEx(verb))) { continue; } e.DoIt(); applied = true; break; } if (applied) { goto Done; } //} if (string.IsNullOrWhiteSpace(verb)) { verb = "Toggle Taskbar Pin"; } const string cmdKeyPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CommandStore\\shell\\Windows.taskbarpin"; var cmdHandler = Reg.ReadString(Registry.LocalMachine, cmdKeyPath, "ExplorerCommandHandler"); if (!string.IsNullOrEmpty(cmdHandler)) { shellKeyPath = $"Software\\Classes\\*\\shell\\{verb}"; Reg.Write(Registry.CurrentUser, shellKeyPath, "ExplorerCommandHandler", cmdHandler); } if (Reg.EntryExists(Registry.CurrentUser, shellKeyPath, "ExplorerCommandHandler")) { link.InvokeVerb(verb); } Done: if (!pin) { return(!IsPinned(file)); } var curLink = GetPinLink(path); if (!File.Exists(curLink)) { return(false); } var target = ShellLink.GetTarget(curLink); var envVar = EnvironmentEx.GetVariableWithPath(target, false, false); if (!target.EqualsEx(envVar)) { FileEx.CreateShellLink(file, curLink); } return(true); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(false); } finally { /* * if (isPresentWindows) * ProcessEx.CurrentPrincipal.RestoreName(); */ if (!string.IsNullOrEmpty(shellKeyPath)) { Reg.RemoveSubKey(Registry.CurrentUser, shellKeyPath); } } }