private ProjectItem GetOrCreateFolder(Project project, string virtualPath) { string[] paths = virtualPath.Split(new char[] { System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); if (paths.Length == 0) { ProjectItem parent = project.ParentProjectItem; if (parent == null) { parent = new ProjectProjectItemAdapter(project); } return(parent); } else { return(GetOrCreateRecursive(project.ProjectItems, paths, 0)); } }
/// <summary> /// The method that creates a new item from the input string. /// </summary> public override void Execute() { if (ownerItem == null && ownerProject == null) { throw new ArgumentNullException(Properties.Resources.OwnerProjectOrItemRequired); } if (ownerItem != null) { ownerProject = ownerItem.ContainingProject; // If we got a parent item, build the virtual path to it // for the real full path we will work againt. string itemPath = String.Empty; DteHelper.BuildPathFromCollection(ownerProject.ProjectItems, ownerItem, ref itemPath); path = System.IO.Path.Combine(itemPath, path); } DTE vs = GetService <DTE>(); ProjectItem containingFolder; string targetPath; using (EnsureProjectFolderAction ensureFolder = new EnsureProjectFolderAction()) { this.Site.Container.Add(ensureFolder); ensureFolder.Path = path; ensureFolder.OwnerProject = ownerProject; ensureFolder.Execute(); containingFolder = ensureFolder.TargetFolder; } if (containingFolder.Object is Project) { containingFolder = new ProjectProjectItemAdapter((Project)containingFolder.Object); } using (EvaluateExpressionAction evaluateExpression = new EvaluateExpressionAction()) { this.Site.Container.Add(evaluateExpression); evaluateExpression.Expression = path; evaluateExpression.Execute(); targetPath = evaluateExpression.ReturnValue.ToString(); } string targetFileName = System.IO.Path.GetFileName(targetPath); // This may be different than the containingFolder variable, // as the EnsureProjectFolder only ensures folders, not // hierarchy of dependent items. So we need to look for // the actual parent which may be a project item, not a folder. ProjectItem parent = DteHelper.FindItemByPath( vs.Solution, System.IO.Path.Combine( DteHelper.BuildPath(ownerProject), /* This call just strips the last segment in the path. "Directory" * can still be a file name, as in the case of dependent items */ System.IO.Path.GetDirectoryName(targetPath) ) ); if (parent == null) { parent = containingFolder; } Debug.Assert(parent != null, "Didn't find parent with path: " + targetPath); addedItem = DteHelper.FindItemByName(parent.ProjectItems, targetFileName, false); if (addedItem != null) { if (overwrite) { OverwriteFile(vs, addedItem.get_FileNames(1), content); addedItem.Delete(); } } addedItem = DteHelper.FindItemByName(parent.ProjectItems, targetFileName, false); if (addedItem == null) { // At the FS level, dependent files are always inside the folder we determined // above using the EnsureProjectFolderAction. string folderPath = System.IO.Path.Combine( System.IO.Path.GetDirectoryName(ownerProject.FileName), DteHelper.BuildPath(containingFolder)); string fullPath = System.IO.Path.Combine(folderPath, targetFileName); if (File.Exists(fullPath)) { OverwriteFile(vs, fullPath, content); addedItem = parent.ProjectItems.AddFromFile(fullPath); } else { string tempfile = System.IO.Path.GetTempFileName(); try { File.WriteAllText(tempfile, content); addedItem = parent.ProjectItems.AddFromTemplate(tempfile, targetFileName); } finally { File.Delete(tempfile); } } } if (open) { Window wnd = addedItem.Open(Constants.vsViewKindPrimary); wnd.Visible = true; wnd.Activate(); } }