public static bool Exists(string path)
        {
#if DOTNET5_4
            string longFilePath = path;
            if (Interop.CrossPlatformHelpers.IsWindows)
            {
                longFilePath = LongPath.ToUncPath(longFilePath);
            }
            return(File.Exists(longFilePath));
#else
            try
            {
                if (String.IsNullOrEmpty(path))
                {
                    return(false);
                }
                path = LongPath.ToUncPath(path);
                bool success = NativeMethods.PathFileExistsW(path);
                if (!success)
                {
                    NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(new int[] { 0, NativeMethods.ERROR_DIRECTORY_NOT_FOUND, NativeMethods.ERROR_FILE_NOT_FOUND });
                }
                var fileAttributes = GetAttributes(path);
                return(success && (FileAttributes.Directory != (fileAttributes & FileAttributes.Directory)));
            }
            catch (ArgumentException) { }
            catch (NotSupportedException) { }  // Security can throw this on ":"
            catch (System.Security.SecurityException) { }
            catch (IOException) { }
            catch (UnauthorizedAccessException) { }

            return(false);
#endif
        }
        public static FileStream Open(string filePath, FileMode mode, FileAccess access, FileShare share)
        {
#if DOTNET5_4
            return(new FileStream(filePath, mode, access, share));
#else
            filePath = LongPath.ToUncPath(filePath);
            SafeFileHandle fileHandle = GetFileHandle(filePath, mode, access, share);
            return(new FileStream(fileHandle, access));
#endif
        }
        /// <summary>
        /// Creates all directories and subdirectories in the specified path unless they already exist.
        /// </summary>
        /// <param name="path">The directory to create.</param>
        public static void CreateDirectory(string path)
        {
#if DOTNET5_4
            Directory.CreateDirectory(path);
#else
            var dir = LongPath.GetDirectoryName(path);
            if (!string.IsNullOrEmpty(dir) && !LongPathDirectory.Exists(dir))
            {
                LongPathDirectory.CreateDirectory(dir);
            }

            path = LongPath.ToUncPath(path);

            if (!NativeMethods.CreateDirectoryW(path, IntPtr.Zero))
            {
                NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(new int[] {
                    NativeMethods.ERROR_SUCCESS,
                    NativeMethods.ERROR_ALREADY_EXISTS
                });
            }
#endif
        }
        public static IEnumerable <string> EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption, FilesOrDirectory filter)
        {
#if DOTNET5_4
            return(Directory.EnumerateFileSystemEntries(path, searchPattern, searchOption));
#else
            NativeMethods.WIN32_FIND_DATA findData;
            NativeMethods.SafeFindHandle  findHandle;
            string currentPath = null;
            int    errorCode   = 0;

            Queue <string> folders    = new Queue <string>();
            String         searchPath = LongPath.Combine(path, searchPattern);
            path          = LongPath.GetDirectoryName(searchPath);
            searchPattern = LongPath.GetFileName(searchPath);
            folders.Enqueue(path);
            while (folders.Count > 0)
            {
                currentPath = folders.Dequeue();
                if (searchOption == SearchOption.AllDirectories)
                {
                    findHandle = NativeMethods.FindFirstFileW(LongPath.Combine(LongPath.ToUncPath(currentPath), "*"), out findData);
                    if (!findHandle.IsInvalid)
                    {
                        do
                        {
                            if (findData.FileName != "." &&
                                findData.FileName != "..")
                            {
                                if (findData.FileAttributes == FileAttributes.Directory)
                                {
                                    folders.Enqueue(LongPath.Combine(currentPath, findData.FileName));
                                }
                            }
                        }while (NativeMethods.FindNextFileW(findHandle, out findData));

                        // Get last Win32 error right after native calls.
                        // Dispose SafeFindHandle will call native methods, it is possible to set last Win32 error.
                        errorCode = Marshal.GetLastWin32Error();
                        if (findHandle != null &&
                            !findHandle.IsInvalid)
                        {
                            findHandle.Dispose();
                        }
                        NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(errorCode,
                                                                              new int[] {
                            NativeMethods.ERROR_SUCCESS,
                            NativeMethods.ERROR_NO_MORE_FILES,
                            NativeMethods.ERROR_FILE_NOT_FOUND
                        });
                    }
                    else
                    {
                        NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(new int[] {
                            NativeMethods.ERROR_SUCCESS,
                            NativeMethods.ERROR_NO_MORE_FILES,
                            NativeMethods.ERROR_FILE_NOT_FOUND
                        });
                    }
                }

                findHandle = NativeMethods.FindFirstFileW(LongPath.Combine(LongPath.ToUncPath(currentPath), searchPattern), out findData);
                if (!findHandle.IsInvalid)
                {
                    do
                    {
                        if (findData.FileName != "." &&
                            findData.FileName != "..")
                        {
                            if ((filter == FilesOrDirectory.All) ||
                                (filter == FilesOrDirectory.Directory && findData.FileAttributes == FileAttributes.Directory) ||
                                (filter == FilesOrDirectory.File && findData.FileAttributes != FileAttributes.Directory))
                            {
                                yield return(LongPath.Combine(currentPath, findData.FileName));
                            }
                        }
                    }while (NativeMethods.FindNextFileW(findHandle, out findData));

                    // Get last Win32 error right after native calls.
                    // Dispose SafeFindHandle will call native methods, it is possible to set last Win32 error.
                    errorCode = Marshal.GetLastWin32Error();
                    if (findHandle != null &&
                        !findHandle.IsInvalid)
                    {
                        findHandle.Dispose();
                    }
                    NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(errorCode,
                                                                          new int[] {
                        NativeMethods.ERROR_SUCCESS,
                        NativeMethods.ERROR_NO_MORE_FILES,
                        NativeMethods.ERROR_FILE_NOT_FOUND
                    });
                }
                else
                {
                    NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(new int[] {
                        NativeMethods.ERROR_SUCCESS,
                        NativeMethods.ERROR_NO_MORE_FILES,
                        NativeMethods.ERROR_FILE_NOT_FOUND
                    });
                }
            }
#endif
        }