<p>I want to copy the entire contents of a directory from one location to another in C#.</p>

<p>There doesn't appear to be a way to do this using <code>System.IO</code> classes without lots of recursion.</p>

<p>There is a method in VB that we can use if we add a reference to <code>Microsoft.VisualBasic</code>:</p>

<pre><code>new Microsoft.VisualBasic.Devices.Computer().
    FileSystem.CopyDirectory( sourceFolder, outputFolder );
</code></pre>

<p>This seems like a rather ugly hack. Is there a better way?</p>

[{'answer_id': 58759, 'author': 'Josef', 'author_id': 5581, 'author_profile': 'https://Stackoverflow.com/users/5581', 'pm_score': 6, 'selected': False, 'text': "<p>Or, if you want to go the hard way, add a reference to your project for Microsoft.VisualBasic and then use the following:</p>\n\n<pre><code>Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(fromDirectory, toDirectory);\n</code></pre>\n\n<p>However, using one of the recursive functions is a better way to go since it won't have to load the VB dll.</p>\n"}, {'answer_id': 58762, 'author': 'Vinko Vrsalovic', 'author_id': 5190, 'author_profile': 'https://Stackoverflow.com/users/5190', 'pm_score': 1, 'selected': False, 'text': '<p>Sorry for the previous code, it still had bugs :( (fell prey to the fastest gun problem)   . Here it is tested and working. The key is the SearchOption.AllDirectories, which eliminates the need for explicit recursion.</p>\n\n<pre><code>string path = "C:\\\\a";\nstring[] dirs = Directory.GetDirectories(path, "*.*", SearchOption.AllDirectories);\nstring newpath = "C:\\\\x";\ntry\n{\n    Directory.CreateDirectory(newpath);\n}\ncatch (IOException ex)\n{\n    Console.WriteLine(ex.Message);\n}\nfor (int j = 0; j &lt; dirs.Length; j++)\n{\n    try\n    {\n        Directory.CreateDirectory(dirs[j].Replace(path, newpath));\n    }\n    catch (IOException ex)\n    {\n        Console.WriteLine(ex.Message);\n    }\n}\n\nstring[] files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);\nfor (int j = 0; j &lt; files.Length; j++)            \n{\n    try\n    {\n        File.Copy(files[j], files[j].Replace(path, newpath));\n    }\n    catch (IOException ex)\n    {\n        Console.WriteLine(ex.Message);\n    }\n}\n</code></pre>\n'}, {'answer_id': 58770, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 3, 'selected': False, 'text': '<p>Here\'s a utility class I\'ve used for IO tasks like this.</p>\n\n<pre><code>using System;\nusing System.Runtime.InteropServices;\n\nnamespace MyNameSpace\n{\n    public class ShellFileOperation\n    {\n        private static String StringArrayToMultiString(String[] stringArray)\n        {\n            String multiString = "";\n\n            if (stringArray == null)\n                return "";\n\n            for (int i=0 ; i&lt;stringArray.Length ; i++)\n                multiString += stringArray[i] + \'\\0\';\n\n            multiString += \'\\0\';\n\n            return multiString;\n        }\n\n        public static bool Copy(string source, string dest)\n        {\n            return Copy(new String[] { source }, new String[] { dest });\n        }\n\n        public static bool Copy(String[] source, String[] dest)\n        {\n            Win32.SHFILEOPSTRUCT FileOpStruct = new Win32.SHFILEOPSTRUCT();\n\n            FileOpStruct.hwnd = IntPtr.Zero;\n            FileOpStruct.wFunc = (uint)Win32.FO_COPY;\n\n            String multiSource = StringArrayToMultiString(source);\n            String multiDest = StringArrayToMultiString(dest);\n            FileOpStruct.pFrom = Marshal.StringToHGlobalUni(multiSource);\n            FileOpStruct.pTo = Marshal.StringToHGlobalUni(multiDest);\n\n            FileOpStruct.fFlags = (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMATION;\n            FileOpStruct.lpszProgressTitle = "";\n            FileOpStruct.fAnyOperationsAborted = 0;\n            FileOpStruct.hNameMappings = IntPtr.Zero;\n\n            int retval = Win32.SHFileOperation(ref FileOpStruct);\n\n            if(retval != 0) return false;\n            return true;\n        }\n\n        public static bool Move(string source, string dest)\n        {\n            return Move(new String[] { source }, new String[] { dest });\n        }\n\n        public static bool Delete(string file)\n        {\n            Win32.SHFILEOPSTRUCT FileOpStruct = new Win32.SHFILEOPSTRUCT();\n\n            FileOpStruct.hwnd = IntPtr.Zero;\n            FileOpStruct.wFunc = (uint)Win32.FO_DELETE;\n\n            String multiSource = StringArrayToMultiString(new string[] { file });\n            FileOpStruct.pFrom = Marshal.StringToHGlobalUni(multiSource);\n            FileOpStruct.pTo =  IntPtr.Zero;\n\n            FileOpStruct.fFlags = (ushort)Win32.ShellFileOperationFlags.FOF_SILENT | (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMATION | (ushort)Win32.ShellFileOperationFlags.FOF_NOERRORUI | (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMMKDIR;\n            FileOpStruct.lpszProgressTitle = "";\n            FileOpStruct.fAnyOperationsAborted = 0;\n            FileOpStruct.hNameMappings = IntPtr.Zero;\n\n            int retval = Win32.SHFileOperation(ref FileOpStruct);\n\n            if(retval != 0) return false;\n            return true;\n        }\n\n        public static bool Move(String[] source, String[] dest)\n        {\n            Win32.SHFILEOPSTRUCT FileOpStruct = new Win32.SHFILEOPSTRUCT();\n\n            FileOpStruct.hwnd = IntPtr.Zero;\n            FileOpStruct.wFunc = (uint)Win32.FO_MOVE;\n\n            String multiSource = StringArrayToMultiString(source);\n            String multiDest = StringArrayToMultiString(dest);\n            FileOpStruct.pFrom = Marshal.StringToHGlobalUni(multiSource);\n            FileOpStruct.pTo = Marshal.StringToHGlobalUni(multiDest);\n\n            FileOpStruct.fFlags = (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMATION;\n            FileOpStruct.lpszProgressTitle = "";\n            FileOpStruct.fAnyOperationsAborted = 0;\n            FileOpStruct.hNameMappings = IntPtr.Zero;\n\n            int retval = Win32.SHFileOperation(ref FileOpStruct);\n\n            if(retval != 0) return false;\n            return true;\n        }\n    }\n}\n</code></pre>\n'}, {'answer_id': 58779, 'author': 'Konrad Rudolph', 'author_id': 1968, 'author_profile': 'https://Stackoverflow.com/users/1968', 'pm_score': 8, 'selected': False, 'text': "<p>Hmm, I think I misunderstand the question but I'm going to risk it. What's wrong with the following straightforward method?</p>\n\n<pre><code>public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) {\n    foreach (DirectoryInfo dir in source.GetDirectories())\n        CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));\n    foreach (FileInfo file in source.GetFiles())\n        file.CopyTo(Path.Combine(target.FullName, file.Name));\n}\n</code></pre>\n\n<p><strong>EDIT</strong> Since this posting has garnered an impressive number of downvotes for such a simple answer to an equally simple question, let me add an explanation. <strong>Please</strong> <em>read this before downvoting</em>.</p>\n\n<p>First of all, <strong>this code is not intendend as a drop-in replacement</strong> to the code in the question. It is for illustration purpose only.</p>\n\n<p><code>Microsoft.VisualBasic.Devices.Computer.FileSystem.CopyDirectory</code> does some additional correctness tests (e.g. whether the source and target are valid directories, whether the source is a parent of the target etc.) that are missing from this answer. That code is probably also more optimized.</p>\n\n<p>That said, the code <em>works well</em>. It <em>has</em> (almost identically) been used in a mature software for years. Apart from the inherent fickleness present with all IO handlings (e.g. what happens if the user manually unplugs the USB drive while your code is writing to it?), there are no known problems.</p>\n\n<p>In particular, I’d like to point out that the use of recursion here is absolutely not a problem. Neither in theory (conceptually, it’s the most elegant solution) nor in practice: <em>this code will not overflow the stack</em>. The stack is large enough to handle even deeply nested file hierarchies. Long before stack space becomes a problem, the folder path length limitation kicks in.</p>\n\n<p>Notice that a <em>malicious user</em> might be able to break this assumption by using deeply-nested directories of one letter each. I haven’t tried this. But just to illustrate the point: in order to make this code overflow on a typical computer, the directories would have to be nested a few <em>thousand</em> times. This is simply not a realistic scenario.</p>\n"}, {'answer_id': 58820, 'author': 'd4nt', 'author_id': 1039, 'author_profile': 'https://Stackoverflow.com/users/1039', 'pm_score': 6, 'selected': False, 'text': '<p>Try this:</p>\n\n<pre><code>Process proc = new Process();\nproc.StartInfo.UseShellExecute = true;\nproc.StartInfo.FileName = Path.Combine(Environment.SystemDirectory, "xcopy.exe");\nproc.StartInfo.Arguments = @"C:\\source C:\\destination /E /I";\nproc.Start();\n</code></pre>\n\n<p>Your xcopy arguments may vary but you get the idea.</p>\n'}, {'answer_id': 690980, 'author': 'Justin R.', 'author_id': 4593, 'author_profile': 'https://Stackoverflow.com/users/4593', 'pm_score': 7, 'selected': False, 'text': '<p>Copied from <a href="http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.aspx" rel="noreferrer">MSDN</a>:</p>\n\n<pre><code>using System;\nusing System.IO;\n\nclass CopyDir\n{\n    public static void Copy(string sourceDirectory, string targetDirectory)\n    {\n        DirectoryInfo diSource = new DirectoryInfo(sourceDirectory);\n        DirectoryInfo diTarget = new DirectoryInfo(targetDirectory);\n\n        CopyAll(diSource, diTarget);\n    }\n\n    public static void CopyAll(DirectoryInfo source, DirectoryInfo target)\n    {\n        Directory.CreateDirectory(target.FullName);\n\n        // Copy each file into the new directory.\n        foreach (FileInfo fi in source.GetFiles())\n        {\n            Console.WriteLine(@"Copying {0}\\{1}", target.FullName, fi.Name);\n            fi.CopyTo(Path.Combine(target.FullName, fi.Name), true);\n        }\n\n        // Copy each subdirectory using recursion.\n        foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())\n        {\n            DirectoryInfo nextTargetSubDir =\n                target.CreateSubdirectory(diSourceSubDir.Name);\n            CopyAll(diSourceSubDir, nextTargetSubDir);\n        }\n    }\n\n    public static void Main()\n    {\n        string sourceDirectory = @"c:\\sourceDirectory";\n        string targetDirectory = @"c:\\targetDirectory";\n\n        Copy(sourceDirectory, targetDirectory);\n    }\n\n    // Output will vary based on the contents of the source directory.\n}\n</code></pre>\n'}, {'answer_id': 2527714, 'author': 'Jens Granlund', 'author_id': 214222, 'author_profile': 'https://Stackoverflow.com/users/214222', 'pm_score': 4, 'selected': False, 'text': '<p>Copy folder recursively without recursion to avoid stack overflow.</p>\n\n<pre><code>public static void CopyDirectory(string source, string target)\n{\n    var stack = new Stack&lt;Folders&gt;();\n    stack.Push(new Folders(source, target));\n\n    while (stack.Count &gt; 0)\n    {\n        var folders = stack.Pop();\n        Directory.CreateDirectory(folders.Target);\n        foreach (var file in Directory.GetFiles(folders.Source, "*.*"))\n        {\n            File.Copy(file, Path.Combine(folders.Target, Path.GetFileName(file)));\n        }\n\n        foreach (var folder in Directory.GetDirectories(folders.Source))\n        {\n            stack.Push(new Folders(folder, Path.Combine(folders.Target, Path.GetFileName(folder))));\n        }\n    }\n}\n\npublic class Folders\n{\n    public string Source { get; private set; }\n    public string Target { get; private set; }\n\n    public Folders(string source, string target)\n    {\n        Source = source;\n        Target = target;\n    }\n}\n</code></pre>\n'}, {'answer_id': 3822913, 'author': 'tboswell', 'author_id': 461882, 'author_profile': 'https://Stackoverflow.com/users/461882', 'pm_score': 10, 'selected': True, 'text': '<p>Much easier</p>\n<pre><code>private static void CopyFilesRecursively(string sourcePath, string targetPath)\n{\n    //Now Create all of the directories\n    foreach (string dirPath in Directory.GetDirectories(sourcePath, &quot;*&quot;, SearchOption.AllDirectories))\n    {\n        Directory.CreateDirectory(dirPath.Replace(sourcePath, targetPath));\n    }\n\n    //Copy all the files &amp; Replaces any files with the same name\n    foreach (string newPath in Directory.GetFiles(sourcePath, &quot;*.*&quot;,SearchOption.AllDirectories))\n    {\n        File.Copy(newPath, newPath.Replace(sourcePath, targetPath), true);\n    }\n}\n</code></pre>\n'}, {'answer_id': 8022011, 'author': 'eduardomozart', 'author_id': 1031340, 'author_profile': 'https://Stackoverflow.com/users/1031340', 'pm_score': 5, 'selected': False, 'text': '<p>This site always have helped me out a lot, and now it\'s my turn to help the others with what I know.</p>\n\n<p>I hope that my code below be useful for someone.</p>\n\n<pre><code>string source_dir = @"E:\\";\nstring destination_dir = @"C:\\";\n\n// substring is to remove destination_dir absolute path (E:\\).\n\n// Create subdirectory structure in destination    \n    foreach (string dir in System.IO.Directory.GetDirectories(source_dir, "*", System.IO.SearchOption.AllDirectories))\n    {\n        System.IO.Directory.CreateDirectory(System.IO.Path.Combine(destination_dir, dir.Substring(source_dir.Length + 1)));\n        // Example:\n        //     &gt; C:\\sources (and not C:\\E:\\sources)\n    }\n\n    foreach (string file_name in System.IO.Directory.GetFiles(source_dir, "*", System.IO.SearchOption.AllDirectories))\n    {\n        System.IO.File.Copy(file_name, System.IO.Path.Combine(destination_dir, file_name.Substring(source_dir.Length + 1)));\n    }\n</code></pre>\n'}, {'answer_id': 9127432, 'author': 'Chris S', 'author_id': 21574, 'author_profile': 'https://Stackoverflow.com/users/21574', 'pm_score': 2, 'selected': False, 'text': '<p>A minor improvement on d4nt\'s answer, as you probably want to check for errors and not have to change xcopy paths if you\'re working on a server and development machine:</p>\n\n<pre><code>public void CopyFolder(string source, string destination)\n{\n    string xcopyPath = Environment.GetEnvironmentVariable("WINDIR") + @"\\System32\\xcopy.exe";\n    ProcessStartInfo info = new ProcessStartInfo(xcopyPath);\n    info.UseShellExecute = false;\n    info.RedirectStandardOutput = true;\n    info.Arguments = string.Format("\\"{0}\\" \\"{1}\\" /E /I", source, destination);\n\n    Process process = Process.Start(info);\n    process.WaitForExit();\n    string result = process.StandardOutput.ReadToEnd();\n\n    if (process.ExitCode != 0)\n    {\n        // Or your own custom exception, or just return false if you prefer.\n        throw new InvalidOperationException(string.Format("Failed to copy {0} to {1}: {2}", source, destination, result));\n    }\n}\n</code></pre>\n'}, {'answer_id': 12543017, 'author': 'Khoi_Vjz_Boy', 'author_id': 1332062, 'author_profile': 'https://Stackoverflow.com/users/1332062', 'pm_score': 2, 'selected': False, 'text': '<p>This is my code hope this help</p>\n\n<pre><code>    private void KCOPY(string source, string destination)\n    {\n        if (IsFile(source))\n        {\n            string target = Path.Combine(destination, Path.GetFileName(source));\n            File.Copy(source, target, true);\n        }\n        else\n        {\n            string fileName = Path.GetFileName(source);\n            string target = System.IO.Path.Combine(destination, fileName);\n            if (!System.IO.Directory.Exists(target))\n            {\n                System.IO.Directory.CreateDirectory(target);\n            }\n\n            List&lt;string&gt; files = GetAllFileAndFolder(source);\n\n            foreach (string file in files)\n            {\n                KCOPY(file, target);\n            }\n        }\n    }\n\n    private List&lt;string&gt; GetAllFileAndFolder(string path)\n    {\n        List&lt;string&gt; allFile = new List&lt;string&gt;();\n        foreach (string dir in Directory.GetDirectories(path))\n        {\n            allFile.Add(dir);\n        }\n        foreach (string file in Directory.GetFiles(path))\n        {\n            allFile.Add(file);\n        }\n\n        return allFile;\n    }\n    private bool IsFile(string path)\n    {\n        if ((File.GetAttributes(path) &amp; FileAttributes.Directory) == FileAttributes.Directory)\n        {\n            return false;\n        }\n        return true;\n    }\n</code></pre>\n'}, {'answer_id': 15648301, 'author': 'Daryl', 'author_id': 814454, 'author_profile': 'https://Stackoverflow.com/users/814454', 'pm_score': 1, 'selected': False, 'text': '<p>Here is an extension method for DirectoryInfo a la <a href="http://msdn.microsoft.com/en-us/library/5axsfwbc.aspx" rel="nofollow">FileInfo.CopyTo</a> (note the <code>overwrite</code> parameter):</p>\n\n<pre><code>public static DirectoryInfo CopyTo(this DirectoryInfo sourceDir, string destinationPath, bool overwrite = false)\n{\n    var sourcePath = sourceDir.FullName;\n\n    var destination = new DirectoryInfo(destinationPath);\n\n    destination.Create();\n\n    foreach (var sourceSubDirPath in Directory.EnumerateDirectories(sourcePath, "*", SearchOption.AllDirectories))\n        Directory.CreateDirectory(sourceSubDirPath.Replace(sourcePath, destinationPath));\n\n    foreach (var file in Directory.EnumerateFiles(sourcePath, "*", SearchOption.AllDirectories))\n        File.Copy(file, file.Replace(sourcePath, destinationPath), overwrite);\n\n    return destination;\n}\n</code></pre>\n'}, {'answer_id': 29463011, 'author': 'toddmo', 'author_id': 1045881, 'author_profile': 'https://Stackoverflow.com/users/1045881', 'pm_score': 2, 'selected': False, 'text': "<p>If you like Konrad's popular answer, but you want the <code>source</code> itself to be a folder under <code>target</code>, rather than putting it's children under the <code>target</code> folder, here's the code for that. It returns the newly created <code>DirectoryInfo</code>, which is handy:</p>\n\n<pre><code>public static DirectoryInfo CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target)\n{\n  var newDirectoryInfo = target.CreateSubdirectory(source.Name);\n  foreach (var fileInfo in source.GetFiles())\n    fileInfo.CopyTo(Path.Combine(newDirectoryInfo.FullName, fileInfo.Name));\n\n  foreach (var childDirectoryInfo in source.GetDirectories())\n    CopyFilesRecursively(childDirectoryInfo, newDirectoryInfo);\n\n  return newDirectoryInfo;\n}\n</code></pre>\n"}, {'answer_id': 35742118, 'author': 'bh_earth0', 'author_id': 3137362, 'author_profile': 'https://Stackoverflow.com/users/3137362', 'pm_score': 2, 'selected': False, 'text': '<p>tboswell \'s replace Proof version (which is resilient to repeating pattern in filepath)</p>\n\n<pre><code>public static void copyAll(string SourcePath , string DestinationPath )\n{\n   //Now Create all of the directories\n   foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories))\n      Directory.CreateDirectory(Path.Combine(DestinationPath ,dirPath.Remove(0, SourcePath.Length ))  );\n\n   //Copy all the files &amp; Replaces any files with the same name\n   foreach (string newPath in Directory.GetFiles(SourcePath, "*.*",  SearchOption.AllDirectories))\n      File.Copy(newPath, Path.Combine(DestinationPath , newPath.Remove(0, SourcePath.Length)) , true);\n    }\n</code></pre>\n'}, {'answer_id': 45199038, 'author': 'iato', 'author_id': 5116032, 'author_profile': 'https://Stackoverflow.com/users/5116032', 'pm_score': 2, 'selected': False, 'text': '<p>You can always use <a href="https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories" rel="nofollow noreferrer">this</a>, taken from Microsofts website. </p>\n\n<pre><code>static void Main()\n{\n    // Copy from the current directory, include subdirectories.\n    DirectoryCopy(".", @".\\temp", true);\n}\n\nprivate static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)\n{\n    // Get the subdirectories for the specified directory.\n    DirectoryInfo dir = new DirectoryInfo(sourceDirName);\n\n    if (!dir.Exists)\n    {\n        throw new DirectoryNotFoundException(\n            "Source directory does not exist or could not be found: "\n            + sourceDirName);\n    }\n\n    DirectoryInfo[] dirs = dir.GetDirectories();\n    // If the destination directory doesn\'t exist, create it.\n    if (!Directory.Exists(destDirName))\n    {\n        Directory.CreateDirectory(destDirName);\n    }\n\n    // Get the files in the directory and copy them to the new location.\n    FileInfo[] files = dir.GetFiles();\n    foreach (FileInfo file in files)\n    {\n        string temppath = Path.Combine(destDirName, file.Name);\n        file.CopyTo(temppath, false);\n    }\n\n    // If copying subdirectories, copy them and their contents to new location.\n    if (copySubDirs)\n    {\n        foreach (DirectoryInfo subdir in dirs)\n        {\n            string temppath = Path.Combine(destDirName, subdir.Name);\n            DirectoryCopy(subdir.FullName, temppath, copySubDirs);\n        }\n    }\n}\n</code></pre>\n'}, {'answer_id': 45614470, 'author': 'Ahmed Sabry', 'author_id': 4707576, 'author_profile': 'https://Stackoverflow.com/users/4707576', 'pm_score': 1, 'selected': False, 'text': '<p>Use this class.</p>\n\n<pre><code>public static class Extensions\n{\n    public static void CopyTo(this DirectoryInfo source, DirectoryInfo target, bool overwiteFiles = true)\n    {\n        if (!source.Exists) return;\n        if (!target.Exists) target.Create();\n\n        Parallel.ForEach(source.GetDirectories(), (sourceChildDirectory) =&gt; \n            CopyTo(sourceChildDirectory, new DirectoryInfo(Path.Combine(target.FullName, sourceChildDirectory.Name))));\n\n        foreach (var sourceFile in source.GetFiles())\n            sourceFile.CopyTo(Path.Combine(target.FullName, sourceFile.Name), overwiteFiles);\n    }\n    public static void CopyTo(this DirectoryInfo source, string target, bool overwiteFiles = true)\n    {\n        CopyTo(source, new DirectoryInfo(target), overwiteFiles);\n    }\n}\n</code></pre>\n'}, {'answer_id': 46857070, 'author': 'malballah', 'author_id': 7633869, 'author_profile': 'https://Stackoverflow.com/users/7633869', 'pm_score': 0, 'selected': False, 'text': '<p>Better than any code (extension method to DirectoryInfo with recursion)</p>\n\n<pre><code>public static bool CopyTo(this DirectoryInfo source, string destination)\n    {\n        try\n        {\n            foreach (string dirPath in Directory.GetDirectories(source.FullName))\n            {\n                var newDirPath = dirPath.Replace(source.FullName, destination);\n                Directory.CreateDirectory(newDirPath);\n                new DirectoryInfo(dirPath).CopyTo(newDirPath);\n            }\n            //Copy all the files &amp; Replaces any files with the same name\n            foreach (string filePath in Directory.GetFiles(source.FullName))\n            {\n                File.Copy(filePath, filePath.Replace(source.FullName,destination), true);\n            }\n            return true;\n        }\n        catch (IOException exp)\n        {\n            return false;\n        }\n    }\n</code></pre>\n'}, {'answer_id': 49461959, 'author': 'Termininja', 'author_id': 3618581, 'author_profile': 'https://Stackoverflow.com/users/3618581', 'pm_score': 1, 'selected': False, 'text': '<p>One variant with only one loop for copying of all folders and files:</p>\n\n<pre><code>foreach (var f in Directory.GetFileSystemEntries(path, "*", SearchOption.AllDirectories))\n{\n    var output = Regex.Replace(f, @"^" + path, newPath);\n    if (File.Exists(f)) File.Copy(f, output, true);\n    else Directory.CreateDirectory(output);\n}\n</code></pre>\n'}, {'answer_id': 51376395, 'author': 'AlexanderD', 'author_id': 5214808, 'author_profile': 'https://Stackoverflow.com/users/5214808', 'pm_score': 2, 'selected': False, 'text': "<p>It may not be performance-aware, but I'm using it for 30MB folders and it works flawlessly. Plus, I didn't like all the amount of code and recursion required for such an easy task.</p>\n<pre><code>var src = &quot;c:\\src&quot;;\nvar dest = &quot;c:\\dest&quot;;\nvar cmp = CompressionLevel.NoCompression;\nvar zip = source_folder + &quot;.zip&quot;;\n\nZipFile.CreateFromDirectory(src, zip, cmp, includeBaseDirectory: false);\nZipFile.ExtractToDirectory(zip, dest_folder);\n\nFile.Delete(zip);\n</code></pre>\n<p><em>Note: ZipFile is available on .NET 4.5+ in the System.IO.Compression namespace</em></p>\n"}, {'answer_id': 53405237, 'author': 'OKEEngine', 'author_id': 662649, 'author_profile': 'https://Stackoverflow.com/users/662649', 'pm_score': 2, 'selected': False, 'text': '<p>My solution is basically a modification of @Termininja\'s answer, however I have enhanced it a bit and it appears to be more than 5 times faster than the accepted answer. </p>\n\n<pre><code>public static void CopyEntireDirectory(string path, string newPath)\n{\n    Parallel.ForEach(Directory.GetFileSystemEntries(path, "*", SearchOption.AllDirectories)\n    ,(fileName) =&gt;\n    {\n        string output = Regex.Replace(fileName, "^" + Regex.Escape(path), newPath);\n        if (File.Exists(fileName))\n        {\n            Directory.CreateDirectory(Path.GetDirectoryName(output));\n            File.Copy(fileName, output, true);\n        }\n        else\n            Directory.CreateDirectory(output);\n    });\n}\n</code></pre>\n\n<p>EDIT: Modifying @Ahmed Sabry to full parallel foreach does produce a better result, however the code uses recursive function and its not ideal in some situation.</p>\n\n<pre><code>public static void CopyEntireDirectory(DirectoryInfo source, DirectoryInfo target, bool overwiteFiles = true)\n{\n    if (!source.Exists) return;\n    if (!target.Exists) target.Create();\n\n    Parallel.ForEach(source.GetDirectories(), (sourceChildDirectory) =&gt;\n        CopyEntireDirectory(sourceChildDirectory, new DirectoryInfo(Path.Combine(target.FullName, sourceChildDirectory.Name))));\n\n    Parallel.ForEach(source.GetFiles(), sourceFile =&gt;\n        sourceFile.CopyTo(Path.Combine(target.FullName, sourceFile.Name), overwiteFiles));\n}\n</code></pre>\n'}, {'answer_id': 55596428, 'author': 'Lakmal', 'author_id': 1547297, 'author_profile': 'https://Stackoverflow.com/users/1547297', 'pm_score': 0, 'selected': False, 'text': '<p>Copy and replace all files of the folder</p>\n\n<pre><code>        public static void CopyAndReplaceAll(string SourcePath, string DestinationPath, string backupPath)\n    {\n            foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories))\n            {\n                Directory.CreateDirectory($"{DestinationPath}{dirPath.Remove(0, SourcePath.Length)}");\n                Directory.CreateDirectory($"{backupPath}{dirPath.Remove(0, SourcePath.Length)}");\n            }\n            foreach (string newPath in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories))\n            {\n                if (!File.Exists($"{ DestinationPath}{newPath.Remove(0, SourcePath.Length)}"))\n                    File.Copy(newPath, $"{ DestinationPath}{newPath.Remove(0, SourcePath.Length)}");\n                else\n                    File.Replace(newPath\n                        , $"{ DestinationPath}{newPath.Remove(0, SourcePath.Length)}"\n                        , $"{ backupPath}{newPath.Remove(0, SourcePath.Length)}", false);\n            }\n    }\n</code></pre>\n'}, {'answer_id': 55981013, 'author': 'Arash.Zandi', 'author_id': 3046588, 'author_profile': 'https://Stackoverflow.com/users/3046588', 'pm_score': 0, 'selected': False, 'text': '<p>The code below is microsoft suggestion <a href="https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories" rel="nofollow noreferrer">how-to-copy-directories</a>\nand it is shared by dear <a href="https://stackoverflow.com/a/45199038/1951524">@iato</a>\nbut it <strong>just copies sub directories and files of source folder recursively</strong> and <strong>doesn\'t copy the source folder it self</strong> (like right click -> copy ).</p>\n\n<p>but <strong>there is a tricky way</strong> below this answer :</p>\n\n<pre><code>private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs = true)\n        {\n            // Get the subdirectories for the specified directory.\n            DirectoryInfo dir = new DirectoryInfo(sourceDirName);\n\n            if (!dir.Exists)\n            {\n                throw new DirectoryNotFoundException(\n                    "Source directory does not exist or could not be found: "\n                    + sourceDirName);\n            }\n\n            DirectoryInfo[] dirs = dir.GetDirectories();\n            // If the destination directory doesn\'t exist, create it.\n            if (!Directory.Exists(destDirName))\n            {\n                Directory.CreateDirectory(destDirName);\n            }\n\n            // Get the files in the directory and copy them to the new location.\n            FileInfo[] files = dir.GetFiles();\n            foreach (FileInfo file in files)\n            {\n                string temppath = Path.Combine(destDirName, file.Name);\n                file.CopyTo(temppath, false);\n            }\n\n            // If copying subdirectories, copy them and their contents to new location.\n            if (copySubDirs)\n            {\n                foreach (DirectoryInfo subdir in dirs)\n                {\n                    string temppath = Path.Combine(destDirName, subdir.Name);\n                    DirectoryCopy(subdir.FullName, temppath, copySubDirs);\n                }\n            }\n        }\n</code></pre>\n\n<p>if you want to copy <strong>contents</strong> of <strong>source</strong> folder and <strong>subfolders</strong> recursively you can simply use it like this :</p>\n\n<pre><code>string source = @"J:\\source\\";\nstring dest= @"J:\\destination\\";\nDirectoryCopy(source, dest);\n</code></pre>\n\n<p>but if you want to copy <strong>the source directory it self</strong> (similar that you have right clicked on source folder and clicked copy then in the destination folder you clicked paste) you should use like this :</p>\n\n<pre><code> string source = @"J:\\source\\";\n string dest= @"J:\\destination\\";\n DirectoryCopy(source, Path.Combine(dest, new DirectoryInfo(source).Name));\n</code></pre>\n'}, {'answer_id': 67476219, 'author': 'Rahul Shukla', 'author_id': 7160482, 'author_profile': 'https://Stackoverflow.com/users/7160482', 'pm_score': 0, 'selected': False, 'text': '<p>Below code to copy all files from source to  destination of given pattern in same folder structure:</p>\n<pre><code>public static void Copy()\n        {\n            string sourceDir = @&quot;C:\\test\\source\\&quot;;\n            string destination = @&quot;C:\\test\\destination\\&quot;;\n\n            string[] textFiles = Directory.GetFiles(sourceDir, &quot;*.txt&quot;, SearchOption.AllDirectories);\n\n            foreach (string textFile in textFiles)\n            {\n                string fileName = textFile.Substring(sourceDir.Length);\n                string directoryPath = Path.Combine(destination, Path.GetDirectoryName(fileName));\n                if (!Directory.Exists(directoryPath))\n                    Directory.CreateDirectory(directoryPath);\n\n                File.Copy(textFile, Path.Combine(directoryPath, Path.GetFileName(textFile)), true);\n            }\n        }\n</code></pre>\n<p><a href="https://i.stack.imgur.com/LlIax.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/LlIax.png" alt="enter image description here" /></a></p>\n'}, {'answer_id': 69069991, 'author': 'kofifus', 'author_id': 460084, 'author_profile': 'https://Stackoverflow.com/users/460084', 'pm_score': 2, 'selected': False, 'text': '<p>Here is a concise and efficient solution:</p>\n<pre><code>namespace System.IO {\n  public static class ExtensionMethods {\n\n    public static void CopyTo(this DirectoryInfo srcPath, string destPath) {\n      Directory.CreateDirectory(destPath);\n      Parallel.ForEach(srcPath.GetDirectories(&quot;*&quot;, SearchOption.AllDirectories), \n        srcInfo =&gt; Directory.CreateDirectory($&quot;{destPath}{srcInfo.FullName[srcPath.FullName.Length..]}&quot;));\n      Parallel.ForEach(srcPath.GetFiles(&quot;*&quot;, SearchOption.AllDirectories), \n        srcInfo =&gt; File.Copy(srcInfo.FullName, $&quot;{destPath}{srcInfo.FullName[srcPath.FullName.Length..]}&quot;, true));\n      });\n    }\n\n  }\n}\n</code></pre>\n<p>To use:</p>\n<pre><code>new DirectoryInfo(sourcePath).CopyTo(destinationPath);\n</code></pre>\n'}, {'answer_id': 69789211, 'author': 'M. Mennan Kara', 'author_id': 1301389, 'author_profile': 'https://Stackoverflow.com/users/1301389', 'pm_score': 0, 'selected': False, 'text': '<p>Just wanted to add my version. It can handle both directories and files, and can overwrite or skip if destination file exists.</p>\n<pre><code>public static void Copy(\n    string source,\n    string destination,\n    string pattern = &quot;*&quot;,\n    bool includeSubFolders = true,\n    bool overwrite = true,\n    bool overwriteOnlyIfSourceIsNewer = false)\n{\n    if (File.Exists(source))\n    {\n        // Source is a file, copy and leave\n        CopyFile(source, destination);\n        return;\n    }\n\n    if (!Directory.Exists(source))\n    {\n        throw new DirectoryNotFoundException($&quot;Source directory does not exists: `{source}`&quot;);\n    }\n\n    var files = Directory.GetFiles(\n        source,\n        pattern,\n        includeSubFolders ?\n            SearchOption.AllDirectories :\n            SearchOption.TopDirectoryOnly);\n\n    foreach (var file in files)\n    {\n        var newFile = file.Replace(source, destination);\n        CopyFile(file, newFile, overwrite, overwriteOnlyIfSourceIsNewer);\n    }\n}\n\nprivate static void CopyFile(\n    string source,\n    string destination,\n    bool overwrite = true,\n    bool overwriteIfSourceIsNewer = false)\n{\n    if (!overwrite &amp;&amp; File.Exists(destination))\n    {\n        return;\n    }\n\n    if (overwriteIfSourceIsNewer &amp;&amp; File.Exists(destination))\n    {\n        var sourceLastModified = File.GetLastWriteTimeUtc(source);\n        var destinationLastModified = File.GetLastWriteTimeUtc(destination);\n        if (sourceLastModified &lt;= destinationLastModified)\n        {\n            return;\n        }\n\n        CreateDirectory(destination);\n        File.Copy(source, destination, overwrite);\n        return;\n    }\n\n    CreateDirectory(destination);\n    File.Copy(source, destination, overwrite);\n}\n\nprivate static void CreateDirectory(string filePath)\n{\n    var targetDirectory = Path.GetDirectoryName(filePath);\n    if (targetDirectory != null &amp;&amp; !Directory.Exists(targetDirectory))\n    {\n        Directory.CreateDirectory(targetDirectory);\n    }\n}\n</code></pre>\n'}, {'answer_id': 70086547, 'author': 'Rui Caramalho', 'author_id': 10756362, 'author_profile': 'https://Stackoverflow.com/users/10756362', 'pm_score': 0, 'selected': False, 'text': '<p>Properties of this code:</p>\n<ul>\n<li>No parallel task, is less performant, but the idea is to treat file by file, so you can log or stop.</li>\n<li>Can skip hiddden files</li>\n<li>Can skip by modified date</li>\n<li>Can break or not (you chose) on a file copy error</li>\n<li>Uses Buffer of 64K for SMB and <code>FileShare.ReadWrite</code> to avoid locks</li>\n<li>Personalize your Exceptions Message</li>\n<li>For Windows</li>\n</ul>\n<blockquote>\n<p><em><strong>Notes</strong></em><br />\n<code>ExceptionToString()</code> is a personal extension that tries to get inner exceptions and display stack. Replace it for <code>ex.Message</code> or any other code.<br />\n<code>log4net.ILog _log</code> I use ==Log4net== You can make your Log in a different way.</p>\n</blockquote>\n<pre class="lang-cs prettyprint-override"><code>/// &lt;summary&gt;\n/// Recursive Directory Copy\n/// &lt;/summary&gt;\n/// &lt;param name=&quot;fromPath&quot;&gt;&lt;/param&gt;\n/// &lt;param name=&quot;toPath&quot;&gt;&lt;/param&gt;\n/// &lt;param name=&quot;continueOnException&quot;&gt;on error, continue to copy next file&lt;/param&gt;\n/// &lt;param name=&quot;skipHiddenFiles&quot;&gt;To avoid files like thumbs.db&lt;/param&gt;\n/// &lt;param name=&quot;skipByModifiedDate&quot;&gt;Does not copy if the destiny file has the same or more recent modified date&lt;/param&gt;\n/// &lt;remarks&gt;\n/// &lt;/remarks&gt;\npublic static void CopyEntireDirectory(string fromPath, string toPath, bool continueOnException = false, bool skipHiddenFiles = true, bool skipByModifiedDate = true)\n{\n    log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);\n    string nl = Environment.NewLine;\n\n    string sourcePath = &quot;&quot;;\n    string destPath = &quot;&quot;;\n    string _exMsg = &quot;&quot;;\n\n    void TreateException(Exception ex)\n    {\n        _log.Warn(_exMsg);\n        if (continueOnException == false)\n        {\n            throw new Exception($&quot;{_exMsg}{nl}----{nl}{ex.ExceptionToString()}&quot;);\n        }\n    }\n\n    try\n    {\n        foreach (string fileName in Directory.GetFileSystemEntries(fromPath, &quot;*&quot;, SearchOption.AllDirectories))\n        {\n            sourcePath = fileName;\n            destPath = Regex.Replace(fileName, &quot;^&quot; + Regex.Escape(fromPath), toPath);\n\n            Directory.CreateDirectory(Path.GetDirectoryName(destPath));\n            \n            _log.Debug(FileCopyStream(sourcePath, destPath,skipHiddenFiles,skipByModifiedDate));\n        }\n    }\n    // Directory must be less than 148 characters, File must be less than 261 characters\n    catch (PathTooLongException)\n    {\n        throw new Exception($&quot;Both paths must be less than 148 characters:{nl}{sourcePath}{nl}{destPath}&quot;);\n    }\n    // Not enough disk space. Cancel further copies\n    catch (IOException ex) when ((ex.HResult &amp; 0xFFFF) == 0x27 || (ex.HResult &amp; 0xFFFF) == 0x70)\n    {\n        throw new Exception($&quot;Not enough disk space:{nl}\'{toPath}\'&quot;);\n    }\n    // used by another process\n    catch (IOException ex) when ((uint)ex.HResult == 0x80070020)\n    {\n        _exMsg = $&quot;File is being used by another process:{nl}\'{destPath}\'{nl}{ex.Message}&quot;;\n        TreateException(ex);\n    }\n    catch (UnauthorizedAccessException ex)\n    {\n        _exMsg = $&quot;Unauthorized Access Exception:{nl}from:\'{sourcePath}\'{nl}to:{destPath}&quot;;\n        TreateException(ex);\n    }\n    catch (Exception ex)\n    {\n        _exMsg = $&quot;from:\'{sourcePath}\'{nl}to:{destPath}&quot;;\n        TreateException(ex);\n    }\n}\n\n/// &lt;summary&gt;\n/// File Copy using Stream 64K and trying to avoid locks with fileshare\n/// &lt;/summary&gt;\n/// &lt;param name=&quot;sourcePath&quot;&gt;&lt;/param&gt;\n/// &lt;param name=&quot;destPath&quot;&gt;&lt;/param&gt;\n/// &lt;param name=&quot;skipHiddenFiles&quot;&gt;To avoid files like thumbs.db&lt;/param&gt;\n/// &lt;param name=&quot;skipByModifiedDate&quot;&gt;Does not copy if the destiny file has the same or more recent modified date&lt;/param&gt;\npublic static string FileCopyStream(string sourcePath, string destPath, bool skipHiddenFiles = true, bool skipByModifiedDate = true)\n{\n    // Buffer should be 64K = 65536\u202c bytes \n    // Increasing the buffer size beyond 64k will not help in any circunstance,\n    // as the underlying SMB protocol does not support buffer lengths beyond 64k.&quot;\n    byte[] buffer = new byte[65536];\n\n    if (!File.Exists(sourcePath))\n        return $&quot;is not a file: \'{sourcePath}\'&quot;;\n\n    FileInfo sourcefileInfo = new FileInfo(sourcePath);\n    FileInfo destFileInfo = null;\n    if (File.Exists(destPath))\n        destFileInfo = new FileInfo(destPath);\n\n    if (skipHiddenFiles)\n    {\n        if (sourcefileInfo.Attributes.HasFlag(FileAttributes.Hidden))\n            return $&quot;Hidden File Not Copied: \'{sourcePath}\'&quot;;\n    }\n\n    using (FileStream input = sourcefileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))\n    using (FileStream output = new FileStream(destPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite, buffer.Length))\n    {\n        if (skipByModifiedDate &amp;&amp; destFileInfo != null)\n        {\n            if (destFileInfo.LastWriteTime &lt; sourcefileInfo.LastWriteTime)\n            {\n                input.CopyTo(output, buffer.Length);\n                destFileInfo.LastWriteTime = sourcefileInfo.LastWriteTime;\n                return $&quot;Replaced: \'{sourcePath}\'&quot;;\n            }\n            else\n            {\n                return $&quot;NOT replaced (more recent or same file): \'{sourcePath}\'&quot;;\n            }\n        }\n        else\n        {\n            input.CopyTo(output, buffer.Length);\n            destFileInfo = new FileInfo(destPath);\n            destFileInfo.LastWriteTime = sourcefileInfo.LastWriteTime;\n            return $&quot;New File: \'{sourcePath}\'&quot;;\n        }\n    }\n}\n</code></pre>\n'}, {'answer_id': 73630610, 'author': 'Rafi Henig', 'author_id': 9369606, 'author_profile': 'https://Stackoverflow.com/users/9369606', 'pm_score': 0, 'selected': False, 'text': '<p>For UWP and Winui 3 (WindowsAppSdk) using <strong>Async</strong> API:</p>\n<pre><code>public async Task CopyAsync(StorageFolder source, StorageFolder dest)\n{\n    foreach (var item in await source.GetItemsAsync())\n\n        if (item is StorageFile file)\n            await file.CopyAsync(dest);\n\n        else if (item is StorageFolder folder)\n            await CopyAsync(folder, await dest.CreateFolderAsync(folder.Name, CreationCollisionOption.OpenIfExists));\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/58744', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/905/']