/// <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}"); }
/// <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);
/// <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);
/// <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);
/// <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);
/// <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)); }
/// <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)); }
/// <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(); } } }
/// <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); } } }
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); } } }
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); }
/// <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; }