public static bool CreatePath(string PathToCreate, Native.Win32ApiErrorCallback OnWin32Error, Action OnCreateDirectory, Action <string> OnExists) { if (IsDirectory(PathToCreate)) { OnExists(PathToCreate); return(true); } if (Native.CreateDirectoryW(PathToCreate, IntPtr.Zero)) { OnCreateDirectory?.Invoke(); return(true); } bool ok = false; if (Marshal.GetLastWin32Error() == (int)Native.Win32Error.ERROR_PATH_NOT_FOUND) { // not found. try to create the parent dir. int LastPos = PathToCreate.LastIndexOf(System.IO.Path.DirectorySeparatorChar); if (LastPos != -1) { string parentDir = PathToCreate.Substring(0, LastPos); if (ok = CreatePath(parentDir, OnWin32Error, OnCreateDirectory, OnExists)) { // parent dir exist/was created ok = Native.CreateDirectoryW(PathToCreate, IntPtr.Zero); if (ok) { OnCreateDirectory?.Invoke(); } else { if (Marshal.GetLastWin32Error() == 183) // ERROR_ALREADY_EXISTS { OnExists?.Invoke(parentDir); ok = true; } else { OnWin32Error?.Invoke(Marshal.GetLastWin32Error(), "CreateDirectoryW", PathToCreate); } } } } } else if (Marshal.GetLastWin32Error() == 183) // ERROR_ALREADY_EXISTS { OnExists?.Invoke(PathToCreate); ok = true; } else { OnWin32Error?.Invoke(Marshal.GetLastWin32Error(), "CreateDirectoryW", PathToCreate); } return(ok); }
public static void Run(string baseDir, IEnumerable <string> dirsToCreate, Native.Win32ApiErrorCallback win32error, Action <string> OnExists, Action OnCreated) { IEnumerable <string> directoriesByLevelAscending = dirsToCreate .OrderBy(dirname => Misc.CountChar(dirname, '\\')); foreach (string dirname in directoriesByLevelAscending) { string FullDirname = Path.Combine(baseDir, dirname); if (CreateDirectory(FullDirname, OnExists, win32error)) { // OnCreated?.Invoke(); } } }
static bool CreateDirectory(string Fullname, Action <string> OnExists, Native.Win32ApiErrorCallback OnError) { bool ok = Native.CreateDirectoryW(Fullname, IntPtr.Zero); if (!ok) { int LastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); if (LastError == 183) // "Cannot create a file when that file already exists." { OnExists(Fullname); } else { OnError(LastError, "CreateDirectoryW", Fullname); } } return(ok); }
static int Main(string[] args) { var opts = GetOpts.Run(args); if (opts == null) { return(1); } opts.baseDir = Misc.GetFullPathLong(opts.baseDir); opts.baseDir = Misc.GetLongFilenameNotation(opts.baseDir); Console.Error.WriteLine($"baseDir: {opts.baseDir}"); if (!File.Exists(opts.filename)) { Console.Error.WriteLine($"input file does not exists. [{opts.filename}]"); return(2); } if (!Misc.IsDirectory(opts.baseDir)) { Console.Error.WriteLine($"base directory is not a directory. [{opts.baseDir}]"); return(4); } IEnumerable <string> directoriesToCreate = File.ReadLines(opts.filename); Stats stats = new Stats(); Task CreateTree = Task.Run(() => { using (var errorWriter = TextWriter.Synchronized(new StreamWriter(@".\crtTreeError.txt", append: false, encoding: Encoding.UTF8))) { Native.Win32ApiErrorCallback OnWin32err = (LastErrorCode, Api, Message) => { errorWriter.WriteLine($"{LastErrorCode}\t{Api}\t{Message}"); Interlocked.Increment(ref stats.error); }; Action <string> OnExists = (name) => Interlocked.Increment(ref stats.exists); Action OnCreated = () => Interlocked.Increment(ref stats.created); if (opts.createPath) { foreach (string dirname in directoriesToCreate) { Misc.CreatePath(Path.Combine(opts.baseDir, dirname), OnWin32err, OnCreated, OnExists); } } else { CreateByDepthAscending.Run(opts.baseDir, directoriesToCreate, OnWin32err, OnExists, OnCreated); } } }); new Spi.StatusLineWriter(Console.Error).WriteUntilFinished( TaskToWaitFor: CreateTree , milliseconds: 1000 , GenerateText: () => $"created: {stats.created:N0}\texists: {stats.exists:N0}\terror: {stats.error:N0}"); return(stats.error > 0 ? 8 : 0); }