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