コード例 #1
0
        /// <summary>
        ///     Creates the specified directory.
        /// </summary>
        /// <param name="path">
        ///     A <see cref="string"/> containing the path of the directory to create.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="path"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///     <paramref name="path"/> is an empty string (""), contains only white
        ///     space, or contains one or more invalid characters as defined in
        ///     <see cref="Path.GetInvalidPathChars()"/>.
        ///     <para>
        ///         -or-
        ///     </para>
        ///     <paramref name="path"/> contains one or more components that exceed
        ///     the drive-defined maximum length. For example, on Windows-based
        ///     platforms, components must not exceed 255 characters.
        /// </exception>
        /// <exception cref="System.IO.PathTooLongException">
        ///     <paramref name="path"/> exceeds the system-defined maximum length.
        ///     For example, on Windows-based platforms, paths must not exceed
        ///     32,000 characters.
        /// </exception>
        /// <exception cref="System.IO.DirectoryNotFoundException">
        ///     <paramref name="path"/> contains one or more directories that could not be
        ///     found.
        /// </exception>
        /// <exception cref="UnauthorizedAccessException">
        ///     The caller does not have the required access permissions.
        /// </exception>
        /// <exception cref="System.IO.IOException">
        ///     <paramref name="path"/> is a file.
        ///     <para>
        ///         -or-
        ///     </para>
        ///     <paramref name="path"/> specifies a device that is not ready.
        /// </exception>
        /// <remarks>
        ///     Note: Unlike <see cref="Directory.CreateDirectory(System.String)"/>, this method only creates
        ///     the last directory in <paramref name="path"/>.
        /// </remarks>
        public static DirectoryInfo CreateDirectory(string path)
        {
            if (Common.IsPathUnc(path))
            {
                return(CreateDirectoryUnc(path));
            }
            var normalizedPath = Path.NormalizeLongPath(path);
            var fullPath       = Path.RemoveLongPathPrefix(normalizedPath);

            var length = fullPath.Length;

            if (length >= 2 && Path.IsDirectorySeparator(fullPath[length - 1]))
            {
                --length;
            }

            var rootLength = Path.GetRootLength(fullPath);

            var pathComponents = new List <string>();

            if (length > rootLength)
            {
                for (var index = length - 1; index >= rootLength; --index)
                {
                    var subPath = fullPath.Substring(0, index + 1);
                    if (!Exists(subPath))
                    {
                        pathComponents.Add(Path.NormalizeLongPath(subPath));
                    }
                    while (index > rootLength && fullPath[index] != System.IO.Path.DirectorySeparatorChar &&
                           fullPath[index] != System.IO.Path.AltDirectorySeparatorChar)
                    {
                        --index;
                    }
                }
            }
            while (pathComponents.Count > 0)
            {
                var str = pathComponents[pathComponents.Count - 1];
                pathComponents.RemoveAt(pathComponents.Count - 1);

                if (NativeMethods.CreateDirectory(str, IntPtr.Zero))
                {
                    continue;
                }

                // To mimic Directory.CreateDirectory, we don't throw if the directory (not a file) already exists
                var errorCode = Marshal.GetLastWin32Error();
                // PR: Not sure this is even possible, we check for existance above.
                //if (errorCode != NativeMethods.ERROR_ALREADY_EXISTS || !Exists(path))
                //{
                throw Common.GetExceptionFromWin32Error(errorCode);
                //}
            }
            return(new DirectoryInfo(fullPath));
        }
コード例 #2
0
        private static DirectoryInfo CreateDirectoryUnc(string path)
        {
            var length = path.Length;

            if (length >= 2 && Path.IsDirectorySeparator(path[length - 1]))
            {
                --length;
            }

            var rootLength = Path.GetRootLength(path);

            var pathComponents = new List <string>();

            if (length > rootLength)
            {
                for (var index = length - 1; index >= rootLength; --index)
                {
                    var subPath = path.Substring(0, index + 1);
                    if (!Exists(subPath))
                    {
                        pathComponents.Add(subPath);
                    }
                    while (index > rootLength && path[index] != System.IO.Path.DirectorySeparatorChar &&
                           path[index] != System.IO.Path.AltDirectorySeparatorChar)
                    {
                        --index;
                    }
                }
            }
            while (pathComponents.Count > 0)
            {
                var str = Path.NormalizeLongPath(pathComponents[pathComponents.Count - 1]);
                pathComponents.RemoveAt(pathComponents.Count - 1);

                if (NativeMethods.CreateDirectory(str, IntPtr.Zero))
                {
                    continue;
                }

                // To mimic Directory.CreateDirectory, we don't throw if the directory (not a file) already exists
                var errorCode = Marshal.GetLastWin32Error();
                if (errorCode != NativeMethods.ERROR_ALREADY_EXISTS || !Exists(path))
                {
                    throw Common.GetExceptionFromWin32Error(errorCode);
                }
            }
            return(new DirectoryInfo(path));
        }