Exemplo n.º 1
0
        /// <summary>
        ///     Sets the specified attributes for the specified path.
        /// </summary>
        /// <param name="path">
        ///     The file or directory to change.
        /// </param>
        /// <param name="attr">
        ///     The attributes to set.
        /// </param>
        public static void SetAttributes(string path, FileAttributes attr)
        {
            var src = Combine(path);

            if (IsDir(src))
            {
                DirectoryEx.SetAttributes(src, attr);
            }
            else
            {
                FileEx.SetAttributes(src, attr);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        ///     Returns processes that have locked the specified paths.
        /// </summary>
        /// <param name="paths">
        ///     An sequence of strings that contains file and/or directory paths to check.
        /// </param>
        /// <exception cref="Win32Exception">
        /// </exception>
        public static IEnumerable <Process> GetLocks(IEnumerable <string> paths)
        {
            if (paths == null)
            {
                return(null);
            }
            var files = new List <string>();

            foreach (var path in paths.Select(Combine))
            {
                if (IsDir(path))
                {
                    var innerFiles = DirectoryEx.GetFiles(path, SearchOption.AllDirectories);
                    if (innerFiles?.Any() ?? false)
                    {
                        files.AddRange(innerFiles);
                    }
                    continue;
                }
                files.Add(path);
            }
            return(files.Any() ? FileEx.GetLocks(files.ToArray()) : null);
        }
Exemplo n.º 3
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));
        }
Exemplo n.º 4
0
        /// <summary>
        ///     <para>
        ///         Deletes any file or directory.
        ///     </para>
        ///     <para>
        ///         Immediately stops all specified processes that are locking this file or directory.
        ///     </para>
        /// </summary>
        /// <param name="path">
        ///     The path of the file or directory to be deleted.
        /// </param>
        /// <param name="elevated">
        ///     true to run this task with administrator privileges if the deletion fails; otherwise,
        ///     false.
        /// </param>
        /// <param name="timelimit">
        ///     The time limit in milliseconds.
        /// </param>
        public static bool ForceDelete(string path, bool elevated = false, int timelimit = 60000)
        {
            var target = Combine(path);

            try
            {
                if (!DirOrFileExists(target))
                {
                    throw new PathNotFoundException(target);
                }

                var locked = false;
                using (var current = Process.GetCurrentProcess())
                {
                    foreach (var p in GetLocks(target).Where(x => x != current))
                    {
                        if (ProcessEx.Terminate(p) || locked)
                        {
                            continue;
                        }
                        locked = true;
                    }
                    if (!locked)
                    {
                        foreach (var p in GetLocks(target).Where(x => x != current))
                        {
                            if (!locked)
                            {
                                locked = true;
                            }
                            p?.Dispose();
                        }
                    }
                }

                var sb      = new StringBuilder();
                var curName = $"{ProcessEx.CurrentName}.exe";
                if (IsDir(target))
                {
                    var tmpDir = DirectoryEx.GetUniqueTempPath();
                    if (!Directory.Exists(tmpDir))
                    {
                        Directory.CreateDirectory(tmpDir);
                    }

                    var helper = FileEx.GetUniqueTempPath("tmp", ".cmd");
                    sb.AppendLine("@ECHO OFF");
                    sb.AppendFormatLine("ROBOCOPY \"{0}\" \"{1}\" /MIR", tmpDir, target);
                    sb.AppendFormatLine("RMDIR /S /Q \"{0}\"", tmpDir);
                    sb.AppendFormatLine("RMDIR /S /Q \"{0}\"", target);
                    sb.AppendLine("EXIT");
                    File.WriteAllText(helper, sb.ToString());

                    var call = $"CALL \"{helper}\"";
                    if (locked)
                    {
                        ProcessEx.SendHelper.WaitForExitThenCmd(call, curName, elevated);
                    }
                    else
                    {
                        using (var p = ProcessEx.Send(call, elevated, false))
                            if (p?.HasExited ?? false)
                            {
                                p.WaitForExit(timelimit);
                            }
                    }

                    DirectoryEx.Delete(tmpDir);
                    DirectoryEx.Delete(target);
                    ProcessEx.SendHelper.WaitThenDelete(helper, elevated);
                }
                else
                {
                    try
                    {
                        File.Delete(target);
                    }
                    catch (Exception ex) when(ex.IsCaught())
                    {
                        if (locked)
                        {
                            ProcessEx.SendHelper.WaitForExitThenDelete(target, curName, true);
                        }
                        else
                        {
                            using (var p = ProcessEx.Send(sb.ToString(), elevated, false))
                                if (p?.HasExited ?? false)
                                {
                                    p.WaitForExit(timelimit);
                                }
                        }
                    }
                }
            }
            catch (Exception ex) when(ex.IsCaught())
            {
                Log.Write(ex);
            }
            return(!DirOrFileExists(target));
        }
Exemplo n.º 5
0
 /// <summary>
 ///     Combines <see cref="Directory.Exists(string)"/> and <see cref="File.Exists(string)"/>
 ///     to determine whether the specified path element exists.
 /// </summary>
 /// <param name="path">
 ///     The file or directory to check.
 /// </param>
 public static bool DirOrFileExists(string path) =>
 DirectoryEx.Exists(path) || FileEx.Exists(path);
Exemplo n.º 6
0
 /// <summary>
 ///     Determines whether the specified path is specified as directory.
 /// </summary>
 /// <param name="path">
 ///     The path to check.
 /// </param>
 public static bool IsDir(string path) =>
 DirectoryEx.Exists(path) && FileEx.MatchAttributes(path, FileAttributes.Directory);
Exemplo n.º 7
0
 /// <summary>
 ///     Determines whether the specified path is specified as reparse
 ///     point.
 /// </summary>
 /// <param name="path">
 ///     The file or directory to check.
 /// </param>
 public static bool DirOrFileIsLink(string path) =>
 IsDir(path) ? DirectoryEx.IsLink(path) : FileEx.IsLink(path);