Q:

How to add subfoldername infront of the filename while copying?

Hey Guys im trying to copy everything in a directory into another
Example folders:
//sourceFolder
//├File1.txt
//├Subfolder1
//| └File2.txt
//|
//└Subfolder2
//  └File3.txt

//targetFolder
//├File1.txt
//├Subfolder1
//| └File2.txt
//|
//└Subfolder2
//  └File3.txt

So far soo good:
void Copy(string sourcePath, string targetPath)
{

foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
    Directory.CreateDirectory(dirPath.Replace(sourcePath, targetPath));

string newPath;
foreach (string srcPath in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories))
    {
    newPath = srcPath.Replace(sourcePath, targetPath);
    File.Copy(srcPath, newPath, true);
    }
}

so actually i am copying everything in an other directory.
but i try to get in the target folder :
//targetFolder
//├aFile1.txt
//├Subfolder1_aFile3.txt
//└Subfolder2_aFile4.txt

Final question:
How can i add the subfolders-name infront of the filename ?

A:

You should use the Path-class, there you find the necessary methods:
public static void Copy(string sourcePath, string targetPath, MergeDirectoryNameOption option = MergeDirectoryNameOption.MergeDirAndFile, string mergeDelimiter = "_")
{
    var files = Directory.EnumerateFiles(sourcePath, "*.*", SearchOption.AllDirectories)
        .Where(filePath => !IsFileInSubDirectoryOf(filePath, targetPath));
    foreach (string srcPath in files)
    {
        string newFilePath = null;
        switch (option)
        {
            case MergeDirectoryNameOption.MergeNon:
                newFilePath = Path.GetFileName(srcPath);
                break;
            case MergeDirectoryNameOption.MergeAllButRoot:
                string[] allDirs = srcPath.Split(Path.DirectorySeparatorChar);
                newFilePath = string.Join(mergeDelimiter, allDirs.Skip(1));
                break;
            case MergeDirectoryNameOption.MergeDirAndFile:
                string[] allDirsButLast = Path.GetDirectoryName(srcPath).Split(Path.DirectorySeparatorChar);
                newFilePath = string.Join(Path.DirectorySeparatorChar.ToString(), allDirsButLast.Skip(1));
                newFilePath = newFilePath + mergeDelimiter + Path.GetFileName(srcPath);
                break;
            default:
                throw new NotSupportedException(string.Format("MergeDirectoryNameOption '{0}' is not supported.", option));
        }
        string newPath = Path.Combine(targetPath, newFilePath);
        Directory.CreateDirectory(Path.GetDirectoryName(newPath));
        File.Copy(srcPath, newPath, true);
    }
}

The relevant part is(Skip(1) skips the root.):
string[] allDirsButLast = Path.GetDirectoryName(srcPath).Split(Path.DirectorySeparatorChar);
newFilePath = string.Join(Path.DirectorySeparatorChar.ToString(), allDirsButLast.Skip(1));
newFilePath = newFilePath + mergeDelimiter + Path.GetFileName(srcPath);

The IsFileInSubDirectoryOf-method is necessary to avoid infinite sub-directories if the target path is a sub-folder of the source-path. The MergeDirectoryNameOption enum is just a bonus, you want MergeDirAndFile. 
public enum MergeDirectoryNameOption
{
    MergeNon = 0,
    MergeAllButRoot = 1,
    MergeDirAndFile = 2
}

public static bool IsFileInSubDirectoryOf(string filePath, string directory)
{
    var dir1 = new DirectoryInfo(directory);
    if (!dir1.Exists || !File.Exists(filePath))
        return false;
    var dir2 = new DirectoryInfo(Path.GetDirectoryName(filePath));
    if (dir2.FullName == dir1.FullName) return true;
    while (dir2.Parent != null)
    {
        if (dir2.Parent.FullName == dir1.FullName)
            return true;
        else
            dir2 = dir2.Parent;
    }
    return false;
}

