Пример #1
0
        /// <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}");
        }
Пример #2
0
        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);
                }
            }
        }