예제 #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
 /// <summary>
 ///     Returns the current user's temporary path in combination with unique name starting with
 ///     a given prefix, followed by a hash of the specified length.
 /// </summary>
 /// <param name="prefix">
 ///     This text is at the beginning of the name.
 ///     <para>
 ///         Uppercase letters are converted to lowercase letters. Supported characters are only
 ///         from '0' to '9' and from 'a' to 'z' but can be completely empty to omit the prefix.
 ///     </para>
 /// </param>
 /// <param name="hashLen">
 ///     The length of the hash. Valid values are 4 through 24.
 /// </param>
 /// <exception cref="ArgumentOutOfRangeException">
 ///     hashLen is not between 4 and 24.
 /// </exception>
 /// <exception cref="ArgumentInvalidException">
 ///     prefix contains invalid characters.
 /// </exception>
 public static string GetUniqueTempPath(string prefix = "tmp", int hashLen = 4) =>
 PathEx.GetUniquePath("%TEMP%", prefix, null, hashLen);
예제 #3
0
 /// <summary>
 ///     Returns the current user's temporary path in combination with unique name starting with
 ///     'tmp' prefix, followed by a hash of the specified length.
 /// </summary>
 /// <param name="hashLen">
 ///     The length of the hash. Valid values are 4 through 24.
 /// </param>
 /// <exception cref="ArgumentOutOfRangeException">
 ///     hashLen is not between 4 and 24.
 /// </exception>
 public static string GetUniqueTempPath(int hashLen) =>
 PathEx.GetUniquePath("%TEMP%", "tmp", null, hashLen);
예제 #4
0
 /// <summary>
 ///     Returns a unique name starting with a given prefix, followed by a hash of the specified
 ///     length.
 /// </summary>
 /// <param name="prefix">
 ///     This text is at the beginning of the name.
 ///     <para>
 ///         Uppercase letters are converted to lowercase letters. Supported characters are only
 ///         from '0' to '9' and from 'a' to 'z' but can be completely empty to omit the prefix.
 ///     </para>
 /// </param>
 /// <param name="hashLen">
 ///     The length of the hash. Valid values are 4 through 24.
 /// </param>
 /// <exception cref="ArgumentOutOfRangeException">
 ///     hashLen is not between 4 and 24.
 /// </exception>
 /// <exception cref="ArgumentInvalidException">
 ///     prefix contains invalid characters.
 /// </exception>
 public static string GetUniqueName(string prefix = "tmp", int hashLen = 4) =>
 PathEx.GetUniqueName(prefix, null, hashLen);
예제 #5
0
 /// <summary>
 ///     Returns a unique name starting with 'tmp' prefix, followed by a hash of the specified
 ///     length.
 /// </summary>
 /// <param name="hashLen">
 ///     The length of the hash. Valid values are 4 through 24.
 /// </param>
 /// <exception cref="ArgumentOutOfRangeException">
 ///     hashLen is not between 4 and 24.
 /// </exception>
 public static string GetUniqueName(int hashLen) =>
 PathEx.GetUniqueName("tmp", null, hashLen);
예제 #6
0
        /// <summary>
        ///     Creates a symbolic link to the specified file or directory based on command
        ///     prompt which allows a simple solution for the elevated execution of this
        ///     order.
        /// </summary>
        /// <param name="linkPath">
        ///     The file or directory to be linked.
        /// </param>
        /// <param name="destPath">
        ///     The fully qualified name of the new link.
        /// </param>
        /// <param name="destIsDir">
        ///     <see langword="true"/> to determine that the destination path is a
        ///     directory; otherwise, <see langword="false"/>.
        /// </param>
        /// <param name="backup">
        ///     <see langword="true"/> to create an backup for existing files; otherwise,
        ///     <see langword="false"/>.
        /// </param>
        /// <param name="elevated">
        ///     <see langword="true"/> to create this link with highest privileges;
        ///     otherwise, <see langword="false"/>.
        /// </param>
        public static bool Create(string linkPath, string destPath, bool destIsDir, bool backup = false, bool elevated = false)
        {
            #region p/invoke

            /*
             * The idea was to replace the code below with this code that uses the
             * p/invoke method to create symbolic links. But this doesn't work
             * without administrator privileges while a CMD function called
             * MKLINK can do that simply as normal user...
             *
             * var dest = PathEx.Combine(targetPath);
             * try
             * {
             *  if (targetIsDir)
             *  {
             *      if (!Directory.Exists(dest))
             *          Directory.CreateDirectory(dest);
             *  }
             *  else
             *  {
             *      if (!File.Exists(dest))
             *          File.Create(dest).Close();
             *  }
             * }
             * catch (Exception ex)
             * {
             *  Log.Write(ex);
             *  return false;
             * }
             *
             * var link = PathEx.Combine(linkPath);
             * try
             * {
             *  var linkDir = Path.GetDirectoryName(link);
             *  if (linkDir != null && !Directory.Exists(linkDir))
             *      Directory.CreateDirectory(linkDir);
             * }
             * catch (Exception ex)
             * {
             *  Log.Write(ex);
             *  return false;
             * }
             *
             * if (PathEx.DirOrFileExists(link))
             *  if (!DirIsLink(link) && backup)
             *      try
             *      {
             *          File.Move(link, link + $"-{{{EnvironmentEx.MachineId}}}.backup");
             *      }
             *      catch (Exception ex)
             *      {
             *          Log.Write(ex);
             *          return false;
             *      }
             *  else
             *      try
             *      {
             *          if (Directory.Exists(link))
             *              Directory.Delete(link);
             *          if (File.Exists(link))
             *              File.Delete(link);
             *      }
             *      catch (Exception ex)
             *      {
             *          Log.Write(ex);
             *      }
             *
             *
             * if (!PathEx.DirOrFileExists(dest) || PathEx.DirOrFileExists(link))
             *  return false;
             *
             * var created = WinApi.SafeNativeMethods.CreateSymbolicLink(link, dest, (WinApi.SymbolicLinkFlags)Convert.ToInt32(targetIsDir));
             * if (created)
             *  SetAttributes(link, FileAttributes.Hidden);
             *
             * return created;
             */

            #endregion

            var dest = PathEx.Combine(destPath);
            try
            {
                if (destIsDir)
                {
                    if (!Directory.Exists(dest))
                    {
                        Directory.CreateDirectory(dest);
                    }
                }
                else
                {
                    if (!File.Exists(dest))
                    {
                        File.Create(dest).Close();
                    }
                }
            }
            catch (Exception ex) when(ex.IsCaught())
            {
                Log.Write(ex);
                return(false);
            }

            var link = PathEx.Combine(linkPath);
            try
            {
                var linkDir = Path.GetDirectoryName(link);
                if (!Directory.Exists(linkDir) && linkDir != null)
                {
                    Directory.CreateDirectory(linkDir);
                }
            }
            catch (Exception ex) when(ex.IsCaught())
            {
                Log.Write(ex);
                return(false);
            }

            var sb = new StringBuilder();
            if (backup && PathEx.DirOrFileExists(link))
            {
                if (!DirectoryEx.IsLink(link))
                {
                    var prior = Resources.BackupFormat.FormatCurrent(link, EnvironmentEx.MachineId);
                    sb.AppendFormatCurrent("MOVE /Y \"{0}\" \"{1}\"", link, prior);
                }
                else
                {
                    Destroy(link, true, true, elevated);
                }
            }

            if (PathEx.DirOrFileExists(link))
            {
                if (sb.Length > 0)
                {
                    sb.Append(" & ");
                }
                sb.AppendFormatCurrent(destIsDir ? "RMDIR /S /Q \"{0}\"" : "DEL /F /Q \"{0}\"", link);
            }

            if (PathEx.DirOrFileExists(dest))
            {
                if (sb.Length > 0)
                {
                    sb.Append(" & ");
                }
                sb.Append("MKLINK");
                if (destIsDir)
                {
                    sb.Append(" /J");
                }
                sb.AppendFormatCurrent(" \"{0}\" \"{1}\" && ATTRIB +H \"{0}\" /L", link, dest);
            }

            if (sb.Length <= 0)
            {
                return(false);
            }

            int?exitCode;
            using (var p = CmdExec.Send(sb.ToStringThenClear(), elevated, false))
            {
                if (p?.HasExited ?? false)
                {
                    p.WaitForExit();
                }
                exitCode = p?.ExitCode;
            }
            return(exitCode == 0 && PathEx.DirOrFileIsLink(link));
        }
예제 #7
0
        /// <summary>
        ///     Determines whether the specified directory exists.
        /// </summary>
        /// <param name="path">
        ///     The directory to check.
        /// </param>
        public static bool Exists(string path)
        {
            var src = PathEx.Combine(path);

            return(Directory.Exists(src));
        }
예제 #8
0
 /// <summary>
 ///     Starts (or reuses) the process resource that is specified by the current
 ///     <see cref="Process"/>.StartInfo property of this <see cref="Process"/> and
 ///     associates it with the component.
 ///     <para>
 ///         If the <see cref="Process"/>.StartInfo.WorkingDirectory parameter is
 ///         undefined, it is created by <see cref="Process"/>.StartInfo.FileName
 ///         parameter.
 ///     </para>
 /// </summary>
 /// <param name="process">
 ///     The <see cref="Process"/> component to start.
 /// </param>
 /// <param name="dispose">
 ///     <see langword="true"/> to release all resources used by the
 ///     <see cref="Process"/> component, if the process has been started;
 ///     otherwise, <see langword="false"/>.
 /// </param>
 public static Process Start(Process process, bool dispose = true)
 {
     try
     {
         if (process == null)
         {
             throw new ArgumentNullException(nameof(process));
         }
         process.StartInfo.FileName = PathEx.Combine(process.StartInfo.FileName);
         if (string.IsNullOrEmpty(process.StartInfo.FileName))
         {
             throw new NullReferenceException();
         }
         if (!File.Exists(process.StartInfo.FileName))
         {
             throw new PathNotFoundException(process.StartInfo.FileName);
         }
         if (process.StartInfo.FileName.EndsWithEx(".lnk"))
         {
             process.Start();
         }
         else
         {
             process.StartInfo.WorkingDirectory = PathEx.Combine(process.StartInfo.WorkingDirectory);
             if (!Directory.Exists(process.StartInfo.WorkingDirectory))
             {
                 var workingDirectory = Path.GetDirectoryName(process.StartInfo.FileName);
                 if (string.IsNullOrEmpty(workingDirectory))
                 {
                     throw new NullReferenceException();
                 }
                 process.StartInfo.WorkingDirectory = workingDirectory;
             }
             if (!process.StartInfo.UseShellExecute && !process.StartInfo.CreateNoWindow && process.StartInfo.WindowStyle == ProcessWindowStyle.Hidden)
             {
                 process.StartInfo.CreateNoWindow = true;
             }
             var processStarted = false;
             if (process.StartInfo.Verb.EqualsEx("RunNotAs"))
             {
                 process.StartInfo.Verb = string.Empty;
                 var processId = 0;
                 try
                 {
                     if (!Elevation.IsAdministrator)
                     {
                         throw new NotSupportedException();
                     }
                     var tokenHandle = IntPtr.Zero;
                     try
                     {
                         var pseudoHandle = WinApi.NativeMethods.GetCurrentProcess();
                         if (pseudoHandle == IntPtr.Zero)
                         {
                             WinApi.ThrowLastError(ExceptionMessages.PseudoHandleNotFound);
                         }
                         if (!WinApi.NativeMethods.OpenProcessToken(pseudoHandle, 0x20, out tokenHandle))
                         {
                             WinApi.ThrowLastError(ExceptionMessages.PseudoHandleTokenAccess);
                         }
                         var newLuId = new WinApi.LuId();
                         if (!WinApi.NativeMethods.LookupPrivilegeValue(null, "SeIncreaseQuotaPrivilege", ref newLuId))
                         {
                             WinApi.ThrowLastError(ExceptionMessages.PrivilegeValueAccess);
                         }
                         var newState = new WinApi.TokenPrivileges
                         {
                             Privileges = new[]
                             {
                                 new WinApi.LuIdAndAttributes
                                 {
                                     Attributes = 0x2,
                                     Luid       = newLuId
                                 }
                             }
                         };
                         if (!WinApi.NativeHelper.AdjustTokenPrivileges(tokenHandle, false, ref newState))
                         {
                             WinApi.ThrowLastError(ExceptionMessages.TokenPrivilegesAdjustment);
                         }
                     }
                     finally
                     {
                         WinApi.NativeMethods.CloseHandle(tokenHandle);
                     }
                     var shellWindow = WinApi.NativeMethods.GetShellWindow();
                     if (shellWindow == IntPtr.Zero)
                     {
                         throw new NullReferenceException();
                     }
                     var shellHandle  = IntPtr.Zero;
                     var shellToken   = IntPtr.Zero;
                     var primaryToken = IntPtr.Zero;
                     try
                     {
                         if (WinApi.NativeMethods.GetWindowThreadProcessId(shellWindow, out var pid) <= 0)
                         {
                             WinApi.ThrowLastError(ExceptionMessages.ShellPidNotFound);
                         }
                         shellHandle = WinApi.NativeMethods.OpenProcess(WinApi.AccessRights.ProcessQueryInformation, false, pid);
                         if (shellHandle == IntPtr.Zero)
                         {
                             WinApi.ThrowLastError(ExceptionMessages.ShellProcessAccess);
                         }
                         if (!WinApi.NativeMethods.OpenProcessToken(shellHandle, 0x2, out shellToken))
                         {
                             WinApi.ThrowLastError(ExceptionMessages.ShellProcessTokenAccess);
                         }
                         if (!WinApi.NativeMethods.DuplicateTokenEx(shellToken, 0x18bu, IntPtr.Zero, WinApi.SecurityImpersonationLevels.SecurityImpersonation, WinApi.TokenTypes.TokenPrimary, out primaryToken))
                         {
                             WinApi.ThrowLastError(ExceptionMessages.ShellProcessTokenDuplication);
                         }
                         var startupInfo = new WinApi.StartupInfo();
                         if (!WinApi.NativeMethods.CreateProcessWithTokenW(primaryToken, 0, process.StartInfo.FileName, process.StartInfo.Arguments, 0, IntPtr.Zero, process.StartInfo.WorkingDirectory, ref startupInfo, out var processInformation))
                         {
                             WinApi.ThrowLastError(ExceptionMessages.NoProcessWithDuplicatedToken);
                         }
                         processId = processInformation.dwProcessId;
                     }
                     finally
                     {
                         WinApi.NativeMethods.CloseHandle(primaryToken);
                         WinApi.NativeMethods.CloseHandle(shellToken);
                         WinApi.NativeMethods.CloseHandle(shellHandle);
                     }
                     processStarted = true;
                 }
                 catch (Exception ex) when(ex.IsCaught())
                 {
                     Log.Write(ex);
                 }
                 if (processStarted && !dispose)
                 {
                     return(Process.GetProcessById(processId));
                 }
             }
             if (!processStarted)
             {
                 process.Start();
             }
         }
         return(process);
     }
     catch (Exception ex) when(ex.IsCaught())
     {
         Log.Write(ex);
         return(null);
     }
     finally
     {
         if (dispose)
         {
             process?.Dispose();
         }
     }
 }
예제 #9
0
        /// <summary>
        ///     Gets all active instances associated with the specified application. If the
        ///     specified name/path is <see langword="null"/>, all running processes are
        ///     returned.
        /// </summary>
        /// <param name="nameOrPath">
        ///     The filename or the full path to the application to check.
        /// </param>
        /// <param name="doubleTap">
        ///     <see langword="true"/> to try to get firstly by the path, then by name;
        ///     otherwise, <see langword="false"/>.
        ///     <para>
        ///         Please note that this option has no effect if the first parameter
        ///         contains only a name.
        ///     </para>
        /// </param>
        public static IEnumerable <Process> GetInstances(string nameOrPath, bool doubleTap = false)
        {
            if (nameOrPath != null && string.IsNullOrWhiteSpace(nameOrPath))
            {
                yield break;
            }
            var path = nameOrPath;

            if (path?.StartsWith("\\", StringComparison.Ordinal) ?? false)
            {
                path = path.TrimStart('\t', ' ', '?', '\\');
            }
            path = PathEx.Combine(path);
            var isPath = path.ContainsEx(Path.DirectorySeparatorChar);

            if (isPath && !File.Exists(path))
            {
                yield break;
            }
            if (!isPath && !doubleTap)
            {
                doubleTap = true;
            }
            var name = nameOrPath;

            if (!string.IsNullOrEmpty(name))
            {
                name = path.EndsWithEx(".com", ".exe", ".scr") ? Path.GetFileNameWithoutExtension(path) : Path.GetFileName(path);
            }
            foreach (var p in Process.GetProcesses())
            {
                if (name == null)
                {
                    yield return(p);

                    continue;
                }
                if (!p.ProcessName.EqualsEx(name))
                {
                    continue;
                }
                var mPath = default(string);
                if (isPath)
                {
                    try
                    {
                        mPath = p.MainModule?.FileName;
                    }
                    catch (Exception ex) when(ex.IsCaught())
                    {
                        if (!(ex is ArgumentException))
                        {
                            Log.Write(ex);
                        }
                    }
                }
                if (mPath?.EqualsEx(path) ?? isPath && doubleTap || doubleTap)
                {
                    yield return(p);
                }
            }
        }
예제 #10
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);
                }
            }
        }
예제 #11
0
 private static string GetVariableFromPathIntern(string path, bool curDir, bool special, out int length)
 {
     try
     {
         if (string.IsNullOrWhiteSpace(path))
         {
             throw new ArgumentNullException(nameof(path));
         }
         var current = path;
         if (current.StartsWith("%", StringComparison.Ordinal) && (current.ContainsEx($"%{Path.DirectorySeparatorChar}", $"%{Path.AltDirectorySeparatorChar}") || current.EndsWith("%", StringComparison.Ordinal)))
         {
             length = current.IndexOf('%', 1);
             return(current.Substring(1, --length));
         }
         if (!PathEx.IsValidPath(path))
         {
             throw new ArgumentInvalidException(nameof(path));
         }
         if (curDir)
         {
             var localDir = PathEx.LocalDir;
             if (current.StartsWithEx(localDir))
             {
                 length = localDir.Length;
                 return("CurDir");
             }
         }
         var table = (Hashtable)Environment.GetEnvironmentVariables();
         foreach (var varKey in table.Keys)
         {
             var varValue = (string)table[varKey];
             if (varValue.Length < 3 || !PathEx.IsValidPath(varValue) || !current.StartsWithEx(varValue))
             {
                 continue;
             }
             length = varValue.Length;
             return((string)varKey);
         }
         if (special)
         {
             var type = typeof(Environment.SpecialFolder);
             foreach (var item in Enum.GetValues(type).Cast <Environment.SpecialFolder>())
             {
                 var folder = Environment.GetFolderPath(item);
                 if (folder.Length < 3 || !current.StartsWithEx(folder))
                 {
                     continue;
                 }
                 var name = Enum.GetName(type, item);
                 length = folder.Length;
                 return(name);
             }
         }
         var sysDrive = Environment.GetEnvironmentVariable("SystemDrive");
         if (!string.IsNullOrEmpty(sysDrive) && current.StartsWithEx(sysDrive))
         {
             length = sysDrive.Length;
             return("SystemDrive");
         }
     }
     catch (InvalidOperationException ex)
     {
         if (Log.DebugMode > 1)
         {
             Log.Write(ex);
         }
     }
     catch (Exception ex) when(ex.IsCaught())
     {
         Log.Write(ex);
     }
     length = 0;
     return(string.Empty);
 }
예제 #12
0
            /// <summary>
            ///     Initializes an instance of the <see cref="IconBrowserDialog"/> class.
            /// </summary>
            /// <param name="path">
            ///     The path of the file to open.
            /// </param>
            /// <param name="backColor">
            ///     The background color of the dialog box.
            /// </param>
            /// <param name="foreColor">
            ///     The foreground color of the dialog box.
            /// </param>
            /// <param name="buttonFace">
            ///     The button color of the dialog box.
            /// </param>
            /// <param name="buttonText">
            ///     The button text color of the dialog box.
            /// </param>
            /// <param name="buttonHighlight">
            ///     The button highlight color of the dialog box.
            /// </param>
            public IconBrowserDialog(string path = "%system%\\imageres.dll", Color?backColor = null, Color?foreColor = null, Color?buttonFace = null, Color?buttonText = null, Color?buttonHighlight = null)
            {
                _components = new Container();
                SuspendLayout();
                var resPath = PathEx.Combine(path);

                if (PathEx.IsDir(resPath))
                {
                    resPath = PathEx.Combine(path, "imageres.dll");
                }
                if (!File.Exists(resPath))
                {
                    resPath = PathEx.Combine("%system%", "imageres.dll");
                }
                var resLoc = Path.GetDirectoryName(resPath);

                AutoScaleDimensions = new SizeF(96f, 96f);
                AutoScaleMode       = AutoScaleMode.Dpi;
                BackColor           = backColor ?? SystemColors.Control;
                ForeColor           = foreColor ?? SystemColors.ControlText;
                Font              = new Font("Consolas", 8.25f, FontStyle.Regular, GraphicsUnit.Point, 0);
                Icon              = GetSystemIcon(IconIndex.DirectorySearch, true, resLoc);
                MaximizeBox       = false;
                MaximumSize       = new Size(680, Screen.FromHandle(Handle).WorkingArea.Height);
                MinimizeBox       = false;
                MinimumSize       = new Size(680, 448);
                Name              = "IconBrowserForm";
                Size              = MinimumSize;
                SizeGripStyle     = SizeGripStyle.Hide;
                StartPosition     = FormStartPosition.CenterScreen;
                Text              = UIStrings.ResourceBrowser;
                _tableLayoutPanel = new TableLayoutPanel
                {
                    BackColor       = Color.Transparent,
                    CellBorderStyle = TableLayoutPanelCellBorderStyle.None,
                    Dock            = DockStyle.Fill,
                    Name            = "tableLayoutPanel",
                    RowCount        = 2
                };
                _tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f));
                _tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 36));
                Controls.Add(_tableLayoutPanel);
                _panel = new Panel
                {
                    AutoScroll  = true,
                    BackColor   = buttonFace ?? SystemColors.ButtonFace,
                    BorderStyle = BorderStyle.FixedSingle,
                    Enabled     = false,
                    ForeColor   = buttonText ?? SystemColors.ControlText,
                    Dock        = DockStyle.Fill,
                    Name        = "panel",
                    TabIndex    = 0
                };
                _panel.Scroll += (s, e) => (s as Panel)?.Update();
                _tableLayoutPanel.Controls.Add(_panel, 0, 0);
                _innerTableLayoutPanel = new TableLayoutPanel
                {
                    BackColor       = Color.Transparent,
                    ColumnCount     = 2,
                    CellBorderStyle = TableLayoutPanelCellBorderStyle.None,
                    Dock            = DockStyle.Fill,
                    Name            = "innerTableLayoutPanel"
                };
                _innerTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
                _innerTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 24));
                _tableLayoutPanel.Controls.Add(_innerTableLayoutPanel, 0, 1);
                _textBox = new TextBox
                {
                    BorderStyle = BorderStyle.FixedSingle,
                    Dock        = DockStyle.Top,
                    Font        = Font,
                    Name        = "textBox",
                    TabIndex    = 1
                };
                _textBox.TextChanged += TextBox_TextChanged;
                _innerTableLayoutPanel.Controls.Add(_textBox, 0, 0);
                _buttonPanel = new Panel
                {
                    Anchor      = AnchorStyles.Top | AnchorStyles.Right,
                    BackColor   = Color.Transparent,
                    BorderStyle = BorderStyle.FixedSingle,
                    Name        = "buttonPanel",
                    Size        = new Size(20, 20)
                };
                _innerTableLayoutPanel.Controls.Add(_buttonPanel, 1, 0);
                _button = new Button
                {
                    BackColor             = buttonFace ?? SystemColors.ButtonFace,
                    BackgroundImage       = GetSystemIcon(IconIndex.Directory, false, resLoc).ToBitmap(),
                    BackgroundImageLayout = ImageLayout.Zoom,
                    Dock      = DockStyle.Fill,
                    FlatStyle = FlatStyle.Flat,
                    Font      = Font,
                    ForeColor = buttonText ?? SystemColors.ControlText,
                    Name      = "button",
                    TabIndex  = 2,
                    UseVisualStyleBackColor = false
                };
                _button.FlatAppearance.BorderSize         = 0;
                _button.FlatAppearance.MouseOverBackColor = buttonHighlight ?? ProfessionalColors.ButtonSelectedHighlight;
                _button.Click += Button_Click;
                _buttonPanel.Controls.Add(_button);
                _progressCircle = new ProgressCircle
                {
                    Active        = false,
                    Anchor        = AnchorStyles.Top | AnchorStyles.Right,
                    BackColor     = Color.Transparent,
                    Dock          = DockStyle.Fill,
                    ForeColor     = (backColor ?? SystemColors.Control).InvertRgb().ToGrayScale(),
                    RotationSpeed = 80,
                    Thickness     = 2,
                    Visible       = true
                };
                _timer = new Timer(_components)
                {
                    Interval = 1
                };
                _timer.Tick += Timer_Tick;
                _iconBoxes   = new List <IconBox>();
                Shown       += (sender, args) => TaskBarProgress.SetState(Handle, TaskBarProgressState.Indeterminate);
                ResumeLayout(false);
                PerformLayout();
                var curPath = PathEx.Combine(path);

                if (!File.Exists(curPath))
                {
                    curPath = resPath;
                }
                if (!File.Exists(curPath))
                {
                    return;
                }
                _textBox.Text = curPath;
            }