private static void BuildStructure(EnvDTE.ProjectItems projectItems, string[] levels, int currentLevel) { if (currentLevel == levels.Length) { return; } var folderName = levels[currentLevel]; var toBeCreated = true; EnvDTE.ProjectItem newProjectItem = null; foreach (EnvDTE.ProjectItem pi in projectItems) { if (pi.Name == folderName && pi.Kind == KIND_FOLDER) { newProjectItem = pi; toBeCreated = false; break; } } if (toBeCreated) { newProjectItem = projectItems.AddFolder(folderName, KIND_FOLDER); } BuildStructure(newProjectItem.ProjectItems, levels, currentLevel + 1); }
// 'parentItem' can be either a Project or ProjectItem private static EnvDTEProjectItem GetOrCreateFolder( EnvDTEProject envDTEProject, object parentItem, string fullPath, string folderRelativePath, string folderName, bool createIfNotExists) { if (parentItem == null) { return(null); } EnvDTEProjectItem subFolder; EnvDTEProjectItems envDTEProjectItems = GetProjectItems(parentItem); if (TryGetFolder(envDTEProjectItems, folderName, out subFolder)) { // Get the sub folder return(subFolder); } else if (createIfNotExists) { // The JS Metro project system has a bug whereby calling AddFolder() to an existing folder that // does not belong to the project will throw. To work around that, we have to manually include // it into our project. if (IsJavaScriptProject(envDTEProject) && Directory.Exists(fullPath)) { bool succeeded = IncludeExistingFolderToProject(envDTEProject, folderRelativePath); if (succeeded) { // IMPORTANT: after including the folder into project, we need to get // a new EnvDTEProjecItems snapshot from the parent item. Otherwise, reusing // the old snapshot from above won't have access to the added folder. envDTEProjectItems = GetProjectItems(parentItem); if (TryGetFolder(envDTEProjectItems, folderName, out subFolder)) { // Get the sub folder return(subFolder); } } return(null); } try { return(envDTEProjectItems.AddFromDirectory(fullPath)); } catch (NotImplementedException) { // This is the case for F#'s project system, we can't add from directory so we fall back // to this impl return(envDTEProjectItems.AddFolder(folderName)); } } return(null); }
private EnvDTE.ProjectItems GetOrCreateFolderItem(EnvDTE.ProjectItems parentItems, string folderPath) { var relativeFolderParts = folderPath.Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries); foreach (string relativefolderPart in relativeFolderParts) { var folderItem = FindItemByName(parentItems, relativefolderPart); if (folderItem == null) { folderItem = parentItems.AddFolder(relativefolderPart); } parentItems = folderItem.ProjectItems; } return(parentItems); }
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; } } } }