/// <summary> /// Copies an existing file or directory to a new location. /// </summary> /// <param name="srcPath"> /// The path to the file or directory to copy. /// </param> /// <param name="destPath"> /// The name of the destination file or directory. /// </param> /// <param name="runAsAdmin"> /// <see langword="true"/> to run this task with administrator privileges; /// otherwise, <see langword="false"/>. /// </param> /// <param name="wait"> /// <see langword="true"/> to wait indefinitely for the associated process to /// exit; otherwise, <see langword="false"/>. /// </param> public static bool Copy(string srcPath, string destPath, bool runAsAdmin = false, bool wait = true) { if (string.IsNullOrWhiteSpace(srcPath) || string.IsNullOrWhiteSpace(destPath)) { return(false); } var src = PathEx.Combine(srcPath); if (!PathEx.DirOrFileExists(src)) { return(false); } var dest = PathEx.Combine(destPath); int exitCode; using (var p = Send($"COPY /Y \"{src}\" \"{dest}\"", runAsAdmin, false)) { if (!wait) { return(true); } if (p?.HasExited ?? false) { p.WaitForExit(); } exitCode = p?.ExitCode ?? 1; } return(exitCode == 0); }
/// <summary> /// Gets the link path from a pinned item based on its file path. /// </summary> /// <param name="path"> /// The file to get the link. /// </param> public static string GetPinLink(string path) { var file = PathEx.Combine(path); var dir = PathEx.Combine(Environment.SpecialFolder.ApplicationData, "Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar"); foreach (var link in DirectoryEx.EnumerateFiles(dir, "*.lnk")) { var target = ShellLink.GetTarget(link); if (string.IsNullOrEmpty(target)) { continue; } if (target.StartsWith("%", StringComparison.Ordinal)) { target = PathEx.Combine(target); } if (!File.Exists(target)) { continue; } if (target.EqualsEx(file)) { return(link); } } return(null); }
/// <summary> /// Creates a new JSON file, writes the specified object graph into to the JSON file, /// and then closes the file. /// </summary> /// <typeparam name="TSource"> /// The type of the source. /// </typeparam> /// <param name="path"> /// The JSON file to create. /// </param> /// <param name="source"> /// The object graph to write to the file. /// </param> /// <param name="overwrite"> /// true to allow an existing file to be overwritten; otherwise, false. /// </param> public static bool SerializeToFile <TSource>(string path, TSource source, bool overwrite = true) { try { if (path == null) { throw new ArgumentNullException(nameof(path)); } var output = Serialize(source); if (output == null) { throw new ArgumentNullException(nameof(output)); } var dest = PathEx.Combine(path); if (!overwrite && File.Exists(dest)) { return(false); } File.WriteAllText(dest, output); return(true); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(false); } }
/// <summary> /// Returns an file type icon of the specified file. /// </summary> /// <param name="path"> /// The file to get the file type icon. /// </param> /// <param name="large"> /// <see langword="true"/> to return the large image; otherwise, /// <see langword="false"/>. /// </param> public static Icon GetFileTypeIcon(string path, bool large = false) { try { path = PathEx.Combine(path); if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } if (!File.Exists(path)) { throw new PathNotFoundException(path); } var shfi = new WinApi.ShFileInfo(); var flags = WinApi.FileInfoFlags.Icon | WinApi.FileInfoFlags.UseFileAttributes; flags |= large ? WinApi.FileInfoFlags.LargeIcon : WinApi.FileInfoFlags.SmallIcon; WinApi.NativeMethods.SHGetFileInfo(path, 0x80, ref shfi, (uint)Marshal.SizeOf(shfi), flags); var ico = (Icon)Icon.FromHandle(shfi.hIcon).Clone(); WinApi.NativeMethods.DestroyIcon(shfi.hIcon); return(ico); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); } return(null); }
/// <summary> /// Extracts the specified resources from the current process to a new file. /// </summary> /// <param name="resData"> /// The resource to extract. /// </param> /// <param name="destPath"> /// The file to create. /// </param> /// <param name="reverseBytes"> /// <see langword="true"/> to invert the order of the bytes in the specified /// sequence before extracting; otherwise, <see langword="false"/>. /// </param> public static void Extract(byte[] resData, string destPath, bool reverseBytes = false) { try { var path = PathEx.Combine(destPath); if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(destPath)); } var dir = Path.GetDirectoryName(path); if (string.IsNullOrEmpty(dir)) { throw new NullReferenceException(); } if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } using var ms = new MemoryStream(resData); var data = ms.ToArray(); if (reverseBytes) { data = data.Reverse().ToArray(); } using var fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write); fs.Write(data, 0, data.Length); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); } }
/// <summary> /// Extracts a large or small icon resource under the specified index, from the /// 'imageres.dll' under specified location, and returns its <see cref="Icon"/> /// instance. /// </summary> /// <param name="index"> /// The index of the icon to extract. /// </param> /// <param name="large"> /// <see langword="true"/> to return the large image; otherwise, /// <see langword="false"/>. /// </param> /// <param name="location"> /// The directory where the 'imageres.dll' file is located. /// </param> public static Icon GetSystemIcon(ImageResourceSymbol index, bool large = false, string location = "%system%") { try { var path = PathEx.Combine(location); if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException(nameof(location)); } if (PathEx.IsDir(path)) { path = Path.Combine(path, "imageres.dll"); } if (!File.Exists(path)) { path = PathEx.Combine("%system%\\imageres.dll"); } return(GetIconFromFile(path, GetImageResourceValue(index), large)); } catch (Exception ex) when(ex.IsCaught()) { if (Log.DebugMode > 1) { Log.Write(ex); } } return(null); }
public static string GetImageResourceName(int value, string location = "%system%") { var path = PathEx.Combine(location); if (!string.IsNullOrWhiteSpace(path) && PathEx.IsDir(path)) { path = Path.Combine(path, "imageres.dll"); } if (!path.EndsWithEx("imageres.dll") || !File.Exists(path)) { path = PathEx.Combine("%system%\\imageres.dll"); } var version = FileEx.GetFileVersion(path); // Windows 10 if (version.Major >= 10) { return(Enum.GetName(typeof(ImageResourceSymbol), value)); } // Windows 7 + 8 if (value < 187) { return(Enum.GetName(typeof(ImageResourceSymbol), value)); } if (value.IsBetween(186, 214)) { return(Enum.GetName(typeof(ImageResourceSymbol), ++value)); } if (value.IsBetween(216, version.Minor < 2 ? 218 : 306)) { return(Enum.GetName(typeof(ImageResourceSymbol), value + (value < 240 ? 17 : 16))); } return(null); }
/// <summary> /// Extracts all large or small icon resources from the file under the /// specified path, and returns its <see cref="Icon"/> instances. /// </summary> /// <param name="path"> /// The path to the file that contains icon resources. /// </param> /// <param name="large"> /// <see langword="true"/> to return the large icons; otherwise, /// <see langword="false"/> to return the small icons. /// </param> /// <exception cref="ArgumentNullException"> /// path is null. /// </exception> /// <exception cref="PathNotFoundException"> /// path not found. /// </exception> /// <exception cref="Win32Exception"> /// path has no icon resources. /// </exception> public static IEnumerable <Icon> GetIconsFromFile(string path, bool large = false) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } path = PathEx.Combine(path); if (!File.Exists(path)) { throw new PathNotFoundException(path); } var count = WinApi.NativeMethods.ExtractIconEx(path, -1, null, null, 0); if (count < 1) { WinApi.ThrowLastError(); yield break; } var ptrs = new IntPtr[count]; count = WinApi.NativeMethods.ExtractIconEx(path, 0, large ? ptrs : null, !large ? ptrs : null, count); for (var i = 0; i < count; i++) { yield return(Icon.FromHandle(ptrs[i])); } }
/// <summary> /// Deletes an existing file or directory. /// </summary> /// <param name="path"> /// The path to the file or directory to be deleted. /// </param> /// <param name="runAsAdmin"> /// <see langword="true"/> to run this task with administrator privileges; /// otherwise, <see langword="false"/>. /// </param> /// <param name="wait"> /// <see langword="true"/> to wait indefinitely for the associated process to /// exit; otherwise, <see langword="false"/>. /// </param> public static bool Delete(string path, bool runAsAdmin = false, bool wait = true) { if (string.IsNullOrWhiteSpace(path)) { return(false); } var src = PathEx.Combine(path); if (!PathEx.DirOrFileExists(src)) { return(true); } int exitCode; using (var p = Send((PathEx.IsDir(src) ? "RMDIR /S /Q \"{0}\"" : "DEL /F /Q \"{0}\"").FormatCurrent(src), runAsAdmin, false)) { if (!wait) { return(true); } if (p?.HasExited ?? false) { p.WaitForExit(); } exitCode = p?.ExitCode ?? 1; } return(exitCode == 0); }
/// <summary> /// Creates a new JSON file, writes the specified object graph into to the JSON /// file, and then closes the file. /// </summary> /// <typeparam name="TSource"> /// The type of the source. /// </typeparam> /// <param name="path"> /// The JSON file to create. /// </param> /// <param name="source"> /// The object graph to write to the file. /// </param> /// <param name="overwrite"> /// <see langword="true"/> to allow an existing file to be overwritten; /// otherwise, <see langword="false"/>. /// </param> /// <param name="formatted"> /// <see langword="true"/> to save the JSON document formatted; otherwise, /// <see langword="false"/>. /// </param> public static bool SerializeToFile <TSource>(string path, TSource source, bool overwrite = true, bool formatted = true) { try { if (path == null) { throw new ArgumentNullException(nameof(path)); } var output = Serialize(source); if (output == null) { throw new NullReferenceException(); } var dest = PathEx.Combine(path); using (var fs = new FileStream(dest, overwrite ? FileMode.Create : FileMode.CreateNew)) if (!formatted) { fs.WriteBytes(output); } else { Format(fs, output); } return(true); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(false); } }
/// <summary> /// Determines whether the current principal has enough privileges to write in the /// specified directory. /// </summary> /// <param name="path"> /// The path to check. /// </param> public static bool WritableLocation(string path) { var result = false; try { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } var dir = PathEx.Combine(path); if (!Directory.Exists(dir)) { dir = Path.GetDirectoryName(dir); } if (!Directory.Exists(dir)) { throw new PathNotFoundException(path); } var acl = Directory.GetAccessControl(dir); foreach (var rule in acl.GetAccessRules(true, true, typeof(NTAccount)).Cast <FileSystemAccessRule>() .Where(rule => (rule.FileSystemRights & FileSystemRights.Write) != 0 && CurrentPrincipal.IsInRole(rule.IdentityReference.Value))) { result = rule.AccessControlType == AccessControlType.Allow; break; } } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); } return(result); }
/// <summary> /// Copies an existing directory to a new location and deletes the source /// directory if this task has been completed successfully. /// </summary> /// <param name="srcDir"> /// The directory to move. /// </param> /// <param name="destDir"> /// The fully qualified name of the destination directory. /// </param> /// <param name="overwrite"> /// <see langword="true"/> to allow existing files to be overwritten; /// otherwise, <see langword="false"/>. /// </param> public static bool Move(string srcDir, string destDir, bool overwrite = false) { if (!Copy(srcDir, destDir, overwrite)) { return(false); } var src = PathEx.Combine(srcDir); var dest = PathEx.Combine(destDir); try { if (!overwrite || GetFullHashCode(src) != GetFullHashCode(dest)) { throw new AggregateException(); } if (!IsLink(src)) { SetAttributes(src, FileAttributes.Directory | FileAttributes.Normal); } Directory.Delete(src, true); return(true); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(false); } }
/// <summary> /// Creates all directories and subdirectories in the specified path unless /// they already exist. /// </summary> /// <param name="path"> /// The directory to create. /// </param> public static bool Create(string path) { try { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } var dir = PathEx.Combine(path); if (Directory.Exists(dir)) { return(true); } if (File.Exists(dir) && !PathEx.IsDir(dir)) { File.Delete(dir); } var di = Directory.CreateDirectory(dir); return(di.Exists); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(false); } }
/// <summary> /// Removes an symbolic link of the specified file or directory link based on command /// prompt which allows a simple solution for the elevated execution of this order. /// </summary> /// <param name="path"> /// The link to be removed. /// </param> /// <param name="pathIsDir"> /// true to determine that the path is a directory; otherwise, false. /// </param> /// <param name="backup"> /// true to restore found backups; otherwise, false. /// </param> /// <param name="elevated"> /// true to remove this link with highest privileges; otherwise, false. /// </param> public static bool Destroy(string path, bool pathIsDir, bool backup = false, bool elevated = false) { var link = PathEx.Combine(path); var isLink = PathEx.DirOrFileIsLink(link); var sb = new StringBuilder(); sb.AppendFormat(CultureConfig.GlobalCultureInfo, pathIsDir ? "RMDIR /Q \"{0}\"" : isLink ? "DEL /F /Q /A:L \"{0}\"" : "DEL /F /Q \"{0}\"", link); var prior = string.Format(CultureConfig.GlobalCultureInfo, Resources.BackupFormat, link, EnvironmentEx.MachineId); if (backup && PathEx.DirOrFileExists(prior)) { sb.AppendFormat(CultureConfig.GlobalCultureInfo, " && MOVE /Y \"{0}\" \"{1}\"", prior, link); } if (sb.Length <= 0) { return(false); } int?exitCode; using (var p = ProcessEx.Send(sb.ToString(), elevated, false)) { if (p?.HasExited ?? false) { p.WaitForExit(); } exitCode = p?.ExitCode; } return(exitCode == 0 && isLink); }
/// <summary> /// Returns the names of files (including their paths) that match the specified /// search pattern in the specified directory, using a value to determine /// whether to search subdirectories. /// </summary> /// <param name="path"> /// The relative or absolute path to the directory to search. This string is /// not case-sensitive. /// </param> /// <param name="searchPattern"> /// The search string to match against the names of files in path. This /// parameter can contain a combination of valid literal path and wildcard (* /// and ?) characters, but doesn't support regular expressions. /// </param> /// <param name="searchOption"> /// One of the enumeration values that specifies whether the search operation /// should include only the current directory or should include all /// subdirectories. /// </param> public static string[] GetFiles(string path, string searchPattern = "*", SearchOption searchOption = SearchOption.TopDirectoryOnly) { try { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } var dir = PathEx.Combine(path); if (!Directory.Exists(dir)) { throw new PathNotFoundException(dir); } var files = Directory.GetFiles(dir, searchPattern, SearchOption.TopDirectoryOnly); if (searchOption == SearchOption.TopDirectoryOnly) { return(files); } var dirs = EnumerateDirectories(dir, searchPattern)?.AsParallel(); if (dirs != null) { files = files.Concat(dirs.SelectMany(s => EnumerateFiles(s, searchPattern, SearchOption.AllDirectories))).ToArray(); } return(files); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(null); } }
/// <summary> /// Deserializes the specified XML file into an object graph. /// </summary> /// <typeparam name="TResult"> /// The type of the result. /// </typeparam> /// <param name="path"> /// The XML file to deserialize. /// </param> /// <param name="defValue"> /// The default value. /// </param> public static TResult DeserializeFile <TResult>(string path, TResult defValue = default) { try { var src = PathEx.Combine(path); if (!File.Exists(src)) { return(defValue); } TResult result; var fs = default(FileStream); try { fs = new FileStream(src, FileMode.Open, FileAccess.Read); using (var xr = XmlReader.Create(fs, new XmlReaderSettings { Async = false })) { fs = null; result = (TResult) new XmlSerializer(typeof(TResult)).Deserialize(xr); } } finally { fs?.Dispose(); } return(result); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(defValue); } }
/// <summary> /// Returns a new string in which all occurrences in this instance are replaced /// with a valid environment variable. /// </summary> /// <param name="path"> /// The path to convert. /// </param> /// <param name="curDir"> /// true to consider the <see cref="Assembly.GetEntryAssembly()"/>.CodeBase value; /// otherwise, false. /// </param> /// <param name="special"> /// true to consider the <see cref="Environment.SpecialFolder"/> values; /// otherwise, false. /// </param> public static string GetVariablePathFull(string path, bool curDir = true, bool special = true) { var output = string.Empty; try { if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException(nameof(path)); } var levels = path.Count(c => c == Path.DirectorySeparatorChar) + 1; var current = PathEx.Combine(path); for (var i = 0; i < levels; i++) { output = GetVariablePath(current, curDir, special); if (!string.IsNullOrEmpty(output)) { break; } current = PathEx.Combine(current, "..").Trim(Path.DirectorySeparatorChar); } if (string.IsNullOrWhiteSpace(output)) { throw new ArgumentNullException(nameof(output)); } var sub = path.Substring(current.Length).Trim(Path.DirectorySeparatorChar); output = output.Trim(Path.DirectorySeparatorChar); output = Path.Combine(output, sub); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); } return(!string.IsNullOrWhiteSpace(output) ? output : path); }
/// <summary> /// Creates a archive that contains the files and directories from the specified /// directory. /// </summary> /// <param name="srcDir"> /// The path to the directory to be archived. /// </param> /// <param name="destPath"> /// The path of the archive to be created. /// </param> public static void ZipDir(string srcDir, string destPath) { try { var src = PathEx.Combine(srcDir); if (string.IsNullOrEmpty(src)) { throw new ArgumentNullException(nameof(src)); } if (!Directory.Exists(src)) { throw new DirectoryNotFoundException(); } var dest = PathEx.Combine(destPath); if (string.IsNullOrEmpty(dest)) { throw new ArgumentNullException(nameof(dest)); } if (!PathEx.IsValidPath(dest)) { throw new ArgumentException(); } if (File.Exists(dest)) { File.Delete(dest); } ZipFile.CreateFromDirectory(src, dest); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); } }
/// <summary> /// Extracts all icon resources from the file under the specified path, and /// returns its <see cref="Tuple{T1, T2}"/> instances with the large icon as /// the first item and the small icon as the second. /// </summary> /// <param name="path"> /// The path to the file that contains icon resources. /// </param> /// <exception cref="ArgumentNullException"> /// path is null. /// </exception> /// <exception cref="PathNotFoundException"> /// path not found. /// </exception> /// <exception cref="Win32Exception"> /// path has no icon resources. /// </exception> public static IEnumerable <Tuple <Icon, Icon> > GetIconPairsFromFile(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } path = PathEx.Combine(path); if (!File.Exists(path)) { throw new PathNotFoundException(path); } var count = WinApi.NativeMethods.ExtractIconEx(path, -1, null, null, 0); if (count < 1) { WinApi.ThrowLastError(); yield break; } var ptrs1 = new IntPtr[count]; var ptrs2 = new IntPtr[count]; count = WinApi.NativeMethods.ExtractIconEx(path, 0, ptrs1, ptrs2, count); for (var i = 0; i < count; i++) { yield return(Tuple.Create(Icon.FromHandle(ptrs1[i]), Icon.FromHandle(ptrs2[i]))); } }
/// <summary> /// Formats the specified JSON file and overwrites it if necessary. /// </summary> /// <exception cref="ArgumentNullException"> /// path is null. /// </exception> /// <exception cref="IOException"> /// path is invalid. /// </exception> public static bool FormatFile(string path) { if (path == null) { throw new ArgumentNullException(nameof(path)); } var srcFile = PathEx.Combine(path); if (!PathEx.IsValidPath(srcFile)) { throw new IOException(); } var srcDir = Path.GetDirectoryName(srcFile); var newFile = PathEx.GetUniquePath(srcDir, "tmp", ".json"); using (var sr = new StreamReader(srcFile)) { using var fs = new FileStream(newFile, FileMode.Create); int count; var ca = new char[4096]; var depth = 0; var isEscape = false; var isValue = false; while ((count = sr.Read(ca, 0, ca.Length)) > 0) { Format(fs, ca, count, ' ', ref depth, ref isEscape, ref isValue); } } if (!FileEx.ContentIsEqual(srcFile, newFile)) { return(FileEx.Move(newFile, srcFile, true)); } FileEx.TryDelete(newFile); return(false); }
/// <summary> /// Changes the character encoding of the specified file. This function supports /// big files as well. /// </summary> /// <param name="file"> /// The file to change. /// </param> /// <param name="encoding"> /// The new character encoding. If the value is NULL it uses the Windows-1252 /// <see cref="Encoding"/> format. /// </param> public static bool ChangeEncoding(string file, Encoding encoding = default) { if (string.IsNullOrEmpty(file)) { return(false); } var srcFile = PathEx.Combine(file); if (!File.Exists(srcFile)) { return(false); } if (encoding == null) { encoding = DefaultEncoding; } if (encoding.Equals(GetEncoding(srcFile))) { return(true); } try { var srcDir = Path.GetDirectoryName(srcFile); var newFile = PathEx.Combine(srcDir, Path.GetRandomFileName()); File.Create(newFile).Close(); FileEx.SetAttributes(newFile, FileAttributes.Hidden); using (var sr = new StreamReader(srcFile)) { var ca = new char[4096]; using (var sw = new StreamWriter(newFile, true, encoding)) { int i; while ((i = sr.Read(ca, 0, ca.Length)) > 0) { sw.Write(ca, 0, i); } } } var srcHash = new Crypto.Md5().EncryptFile(srcFile); var newHash = new Crypto.Md5().EncryptFile(newFile); if (srcHash.Equals(newHash, StringComparison.Ordinal)) { File.Delete(newFile); return(true); } File.Delete(srcFile); File.Move(newFile, srcFile); FileEx.SetAttributes(srcFile, FileAttributes.Normal); return(true); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(false); } }
/// <summary> /// Returns the size, in bytes, of the specified directory. /// </summary> /// <param name="path"> /// The directory to get the size. /// </param> /// <param name="searchOption"> /// One of the enumeration values that specifies whether the operation should /// include only the current directory or all subdirectories. /// </param> public static long GetSize(string path, SearchOption searchOption = SearchOption.AllDirectories) { var dir = PathEx.Combine(path); if (!Directory.Exists(dir)) { return(0L); } var di = new DirectoryInfo(dir); return(di.GetSize(searchOption)); }
/// <summary> /// Returns the total amount of free space available on the drive of the /// specified directory, in bytes. /// </summary> /// <param name="path"> /// The directory to check. /// </param> public static long GetFreeSpace(string path) { var dir = PathEx.Combine(path); if (!Directory.Exists(dir)) { return(0L); } var di = new DirectoryInfo(dir); return(di.GetFreeSpace()); }
/// <summary> /// Gets the character encoding of the specified file. /// </summary> /// <param name="file"> /// The file to check. /// </param> /// <param name="defEncoding"> /// The default character encoding, which is returned if no character encoding /// was found. If <see langword="null"/>, <see cref="Ansi"/> is used. /// </param> public static Encoding GetEncoding(string file, Encoding defEncoding = default) { var path = PathEx.Combine(file); var encoding = defEncoding ?? Ansi; if (!File.Exists(path)) { return(encoding); } using var sr = new StreamReader(file, true); sr.Peek(); return(sr.CurrentEncoding); }
/// <summary> /// Determines whether the specified directory is specified as reparse point. /// </summary> /// <param name="path"> /// The directory to check. /// </param> public static bool IsLink(string path) { try { var src = PathEx.Combine(path); var di = new DirectoryInfo(src); return(di.IsLink()); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(false); } }
/// <summary> /// Plays the specified sound file. /// </summary> /// <param name="path"> /// THe full path of the sound file to play. /// </param> /// <param name="loop"> /// true to loop the sound; otherwise, false. /// </param> /// <param name="volume"> /// The sound volume value, in percent. /// </param> public static void Play(string path, bool loop = false, int volume = 100) { path = PathEx.Combine(path); if (!File.Exists(path)) { return; } if (GetSoundVolume() != volume) { SetSoundVolume(volume); } SndOpen(path); SndPlay(loop); }
/// <summary> /// Determines whether the specified path specifies the specified attributes. /// </summary> /// <param name="path"> /// The directory to check. /// </param> /// <param name="attr"> /// The attributes to match. /// </param> public static bool MatchAttributes(string path, FileAttributes attr) { try { var src = PathEx.Combine(path); var di = new DirectoryInfo(src); return(di.MatchAttributes(attr)); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(false); } }
/// <summary> /// Copies an existing directory to a new location. /// </summary> /// <param name="srcDir"> /// The directory to copy. /// </param> /// <param name="destDir"> /// The fully qualified name of the destination directory. /// </param> /// <param name="subDirs"> /// <see langword="true"/> to include subdirectories; otherwise, /// <see langword="false"/>. /// </param> /// <param name="overwrite"> /// <see langword="true"/> to allow existing files to be overwritten; /// otherwise, <see langword="false"/>. /// </param> public static bool Copy(string srcDir, string destDir, bool subDirs = true, bool overwrite = false) { try { if (string.IsNullOrEmpty(srcDir)) { throw new ArgumentNullException(nameof(srcDir)); } var src = PathEx.Combine(srcDir); var di = new DirectoryInfo(src); if (!di.Exists) { throw new PathNotFoundException(di.FullName); } if (string.IsNullOrEmpty(destDir)) { throw new ArgumentNullException(nameof(destDir)); } var dest = PathEx.Combine(destDir); if (!Directory.Exists(dest)) { Directory.CreateDirectory(dest); } foreach (var f in di.EnumerateFiles()) { var p = Path.Combine(dest, f.Name); if (File.Exists(p) && !overwrite) { continue; } f.CopyTo(p, overwrite); } if (!subDirs) { return(true); } if (di.EnumerateDirectories().Any(x => !x.Copy(Path.Combine(dest, x.Name), true, overwrite))) { throw new OperationCanceledException(); } return(true); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(false); } }
/// <summary> /// Waits for the specified seconds to delete the target at the specified path. /// </summary> /// <param name="path"> /// The path to the file or directory to be deleted. /// </param> /// <param name="seconds"> /// The time to wait in seconds. /// </param> /// <param name="runAsAdmin"> /// <see langword="true"/> to run this task with administrator privileges; /// otherwise, <see langword="false"/>. /// </param> /// <param name="dispose"> /// <see langword="true"/> to release all resources used by the /// <see cref="Process"/> component, if this task has been started; otherwise, /// <see langword="false"/>. /// </param> public static Process WaitThenDelete(string path, int seconds = 5, bool runAsAdmin = false, bool dispose = true) { if (string.IsNullOrWhiteSpace(path)) { return(null); } var src = PathEx.Combine(path); if (!PathEx.DirOrFileExists(src)) { return(null); } var time = seconds < 1 ? 1 : seconds > 3600 ? 3600 : seconds; var command = (PathEx.IsDir(src) ? "RMDIR /S /Q \"{0}\"" : "DEL /F /Q \"{0}\"").FormatCurrent(src); return(WaitThenCmd(command, time, runAsAdmin, dispose)); }
/// <summary> /// Changes the character encoding of the specified file. This function /// supports big files as well. /// </summary> /// <param name="file"> /// The file to change. /// </param> /// <param name="encoding"> /// The new character encoding. If <see langword="null"/>, <see cref="Ansi"/> /// is used. /// </param> public static bool ChangeEncoding(string file, Encoding encoding = default) { if (string.IsNullOrEmpty(file)) { return(false); } var srcFile = PathEx.Combine(file); if (!File.Exists(srcFile)) { return(false); } encoding ??= Ansi; if (encoding.Equals(GetEncoding(srcFile))) { return(true); } try { var srcDir = Path.GetDirectoryName(srcFile); var newFile = PathEx.Combine(srcDir, Path.GetRandomFileName()); File.Create(newFile).Close(); using (var sr = new StreamReader(srcFile)) { using var sw = new StreamWriter(newFile, true, encoding); int i; var ca = new char[4096]; while ((i = sr.Read(ca, 0, ca.Length)) > 0) { sw.Write(ca, 0, i); } } if (!FileEx.ContentIsEqual(srcFile, newFile)) { return(FileEx.Move(newFile, srcFile, true)); } FileEx.TryDelete(newFile); return(false); } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); return(false); } }