Beispiel #1
0
        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);
        }
Beispiel #2
0
        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();
                }
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }