// Note: In the Tuple, the first item is the file full path, and the second item is any object that accompanies the file. public FileTreeWalker(IEnumerable <Tuple <string, object> > filesPathsAndUserState) { _thisRootFolder = new FolderWalker(".", ""); foreach (Tuple <string, object> filePathAndUserState in filesPathsAndUserState) { string filePath = filePathAndUserState.Item1; object userState = filePathAndUserState.Item2; string normalizedFilePath = filePath.Replace('/', '\\'); //make sure we have a consistent separator between the different elements. string[] splittedPath = normalizedFilePath.Split('\\'); int splittedPathLength = splittedPath.Length; //now we loop through the path's elements to create/go through the folders: FolderWalker currentFolder = _thisRootFolder; for (int i = 0; i < splittedPathLength - 1; ++i) { string folderName = splittedPath[i]; if (!string.IsNullOrWhiteSpace(folderName)) { currentFolder = currentFolder.GetSubFolderOrCreateIfNotExists(folderName); } } if (!FoldersHelper.IsAFolder(filePath)) { //create the file. currentFolder.GetFileOrCreateIfNotExists(splittedPath[splittedPathLength - 1], userState); } } }
/// <summary> /// Returns the ProjectItems contained in the passed collection, as well as the "sub project items", which /// are the project items that are dependent on other project items. For example, "MainPage.xaml.cs" is /// a sub project item of "MainPage.xaml". /// </summary> /// <param name="parentCollection">The collection of project items.</param> /// <returns></returns> static IEnumerable <EnvDTE.ProjectItem> GetFilesIncludingSubFiles(EnvDTE.ProjectItems parentCollection) { foreach (EnvDTE.ProjectItem projectItem in parentCollection) { if (!FoldersHelper.IsAFolder(projectItem)) { yield return(projectItem); foreach (EnvDTE.ProjectItem subProjectItem in GetFilesIncludingSubFiles(projectItem.ProjectItems)) { yield return(subProjectItem); } } } }
static void CopyFilesAndFoldersRecursively(IEnumerable <ProjectItemWrapper> sourceProjectItems, EnvDTE.ProjectItems destinationProjectItems, Context.CopyOrAddAsLink howToDealWithCSharpFiles, int level = 1) { if (!StaticAbortProcessing) { foreach (ProjectItemWrapper sourceItem in sourceProjectItems) { string sourceItemName = sourceItem.GetName(); string sourceItemFullPath = sourceItem.GetFullPath(); //--------------------- // If it is a folder: //--------------------- if (FoldersHelper.IsAFolder(sourceItemFullPath)) { // If it is NOT the "Properties" folder (which exists by default in all projects): if (level != 1 || sourceItemName.ToLower() != "properties") { // Create a new folder with the same name in the destination project: EnvDTE.ProjectItem newFolder = destinationProjectItems.AddFolder(sourceItemName); // Log: AddLogEntryOnUIThread(string.Format(@"Created folder ""{0}"".", sourceItemName)); // Continue the recursion: CopyFilesAndFoldersRecursively(sourceItem.GetChildItems(), newFolder.ProjectItems, howToDealWithCSharpFiles, level + 1); } } //--------------------- // If it is a file: //--------------------- else { EnvDTE.ProjectItem newFile = null; if (sourceItemFullPath.ToLower().EndsWith(".cs")) { //--------------------- // C# file: //--------------------- // Check if the file exists (this can be the case for example if we previously copied a file such as "UserControl.xaml", which automatically copies its child "UserControl.xaml.cs"): EnvDTE.ProjectItem existingItem = FindProjectItemOrNull(sourceItemName, destinationProjectItems); // Copy the file or add it as link: if (howToDealWithCSharpFiles == Context.CopyOrAddAsLink.Copy) { // Copy only if the file is not already there: if (existingItem == null) { newFile = destinationProjectItems.AddFromFileCopy(sourceItemFullPath); } // Log: AddLogEntryOnUIThread(string.Format(@"Copied file ""{0}"".", sourceItemName)); } else if (howToDealWithCSharpFiles == Context.CopyOrAddAsLink.AddAsLink) { // Delete the copied file in order to replace it with a linked file (this can happen for example if we previously copied a file such as "UserControl.xaml", which automatically copies its child "UserControl.xaml.cs", so we need to delete this child): if (existingItem != null) { existingItem.Delete(); } // Add the file "as link": newFile = destinationProjectItems.AddFromFile(sourceItemFullPath); // Log: AddLogEntryOnUIThread(string.Format(@"Added file ""{0}"" as link.", sourceItemName)); } else { throw new NotSupportedException(); } } else if (sourceItemFullPath.ToLower().EndsWith(".xaml") || DoesFileHaveOneOfTheseExtensions(sourceItemFullPath, ExtensionsOfFilesToCopy)) // JPG, PNG, etc. { //--------------------- // XAML file: //--------------------- // Copy the file: newFile = destinationProjectItems.AddFromFileCopy(sourceItemFullPath); // Log: AddLogEntryOnUIThread(string.Format(@"Copied file ""{0}"".", sourceItemName)); } // Continue the recursion: if (newFile != null) { CopyFilesAndFoldersRecursively(sourceItem.GetChildItems(), newFile.ProjectItems, howToDealWithCSharpFiles, level + 1); } } if (StaticAbortProcessing) { break; } } } }