/// <summary>
        /// Retrieves the set of processes that are currently locking the file (if any).
        /// </summary>
        /// <param name="fileInfo">A file to test.</param>
        /// <returns>A set of processes that hold a lock on <paramref name="fileInfo"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="fileInfo"/> is <c>null</c>.</exception>
        public static IReadOnlyCollection <IProcessInfo> GetLockingProcesses(this FileInfo fileInfo)
        {
            if (fileInfo == null)
            {
                throw new ArgumentNullException(nameof(fileInfo));
            }

            return(RestartManager.GetLockingProcesses(fileInfo.FullName));
        }
        /// <summary>
        /// Determines whether the file is locked by any process.
        /// </summary>
        /// <param name="fileInfo">A file to test.</param>
        /// <returns><c>true</c> if any processes hold a lock on the file, otherwise <c>false</c>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="fileInfo"/> is <c>null</c>.</exception>
        public static bool IsFileLocked(this FileInfo fileInfo)
        {
            if (fileInfo == null)
            {
                throw new ArgumentNullException(nameof(fileInfo));
            }

            if (!Platform.SupportsRestartManager)
            {
                return(IsSimpleFileLocked(fileInfo));
            }

            return(RestartManager.GetLockingProcesses(fileInfo.FullName).Count > 0);
        }
Exemple #3
0
        /// <summary>
        /// When an exception is thrown due to a lock held on a file, this method will rethrow an exception with more information on which files were locked and which processes were holding the lock.
        /// </summary>
        /// <param name="exception">The exception that was thrown due to a lock held on a file.</param>
        /// <param name="fileNames">A collection of file paths that could have been locked upon.</param>
        /// <returns><c>false</c> if the exception was not held due to a lock on a file, or if there are no locked files.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="exception"/> or <paramref name="fileNames"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">An entry of the <paramref name="fileNames"/> collection is <c>null</c>.</exception>
        public static bool RethrowWithLockingInformation(this Exception exception, IEnumerable <string> fileNames)
        {
            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }
            if (fileNames == null)
            {
                throw new ArgumentNullException(nameof(fileNames));
            }
            if (fileNames.Any(f => f == null))
            {
                throw new ArgumentException("A null filename was provided.", nameof(fileNames));
            }

            if (!(exception is IOException ioex) || !ioex.IsFileLocked())
            {
                return(false);
            }

            var lockers = RestartManager.GetLockingProcesses(fileNames);

            if (lockers.Count == 0)
            {
                return(false);
            }

            const int max     = 10;
            var       builder = new StringBuilder();

            builder.Append(exception.Message);
            builder.Append(" ");

            var message = FormatLockingMessage(lockers, fileNames, max);

            builder.Append(message);

            // Unable to set HResult *and* InnerException via public methods/ctors.
            // Must use reflection to set the HResult while using the ctor to set the InnerException.
            // Nasty but necessary.
            var ex      = new IOException(builder.ToString(), exception);
            var hresult = Marshal.GetHRForException(exception);

            SetHResultMethod?.Invoke(ex, new object[] { hresult });

            throw ex;
        }