internal static void CreateNewFile(NodejsProjectNode projectNode, uint containerId) { using (var dialog = new NewFileNameForm("")) { if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { var itemName = dialog.TextBox.Text; if (string.IsNullOrWhiteSpace(itemName)) { return; } itemName = itemName.Trim(); var pResult = new VSADDRESULT[1]; projectNode.AddItem( containerId, // Identifier of the container folder. VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE, // Indicate that we want to create this new file by cloning a template file. itemName, 1, // Number of templates in the next parameter. Must be 1 if using VSADDITEMOP_CLONEFILE. new string[] { Path.GetTempFileName() }, // Array contains the template file path. IntPtr.Zero, // Handle to the Add Item dialog box. Must be Zero if using VSADDITEMOP_CLONEFILE. pResult); } } }
/// <summary> /// Adds one or more files to the project. /// </summary> public async Task <IEnumerable <PhysicalFile> > AddExistingFilesAsync(params string[] filePaths) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); GetItemInfo(out IVsHierarchy hierarchy, out uint itemId, out _); VSADDRESULT[] result = new VSADDRESULT[filePaths.Count()]; IVsProject ip = (IVsProject)hierarchy; ErrorHandler.ThrowOnFailure(ip.AddItem(itemId, VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE, string.Empty, (uint)filePaths.Count(), filePaths, IntPtr.Zero, result)); List <PhysicalFile> files = new(); foreach (string filePath in filePaths) { PhysicalFile?file = await PhysicalFile.FromFileAsync(filePath); if (file != null) { files.Add(file); } } return(files); }
/// <summary> /// Finds or create a folder. /// </summary> /// <param name="folderName">Name of the folder.</param> /// <returns></returns> public ProjectNode FindOrCreateFolder(string folderName) { if (string.IsNullOrEmpty(folderName) || folderName == ".") { return(this); } DirectoryInfo di = new DirectoryInfo(System.IO.Path.Combine(this.RelativePath, folderName)); HierarchyNode subFolder = FindByName(di.Name); if (subFolder == null) { if (!Directory.Exists(di.FullName)) { Directory.CreateDirectory(di.FullName); } VSADDRESULT result = VSADDRESULT.ADDRESULT_Cancel; int hr = project.AddItem(this.ItemId, (VSADDITEMOPERATION.VSADDITEMOP_OPENFILE), di.Name, 1, new string[] { di.FullName }, IntPtr.Zero, new VSADDRESULT[] { result }); Marshal.ThrowExceptionForHR(hr); } subFolder = FindByName(di.Name); if (subFolder != null) { return(new ProjectNode(subFolder, subFolder.ItemId)); } return(null); }
/// <summary> /// Create a file with the given template file and add it to the parent node. /// </summary> /// <param name="templateFile">The name of the template zip file.</param> /// <param name="parentNode">The node to which the new file will be added.</param> /// <param name="fileName">The name of the file to be created.</param> /// <returns>true if file is added successfully.</returns> public async Task <bool> CreateFileAsync(string templateFile, IProjectTree parentNode, string fileName) { Requires.NotNull(templateFile, nameof(templateFile)); Requires.NotNull(parentNode, nameof(parentNode)); Requires.NotNull(fileName, nameof(fileName)); string templateLanguage = await GetTemplateLanguageAsync().ConfigureAwait(false); if (string.IsNullOrEmpty(templateLanguage)) { return(false); } await _projectVsServices.ThreadingService.SwitchToUIThread(); string templateFilePath = _dteServices.Solution.GetProjectItemTemplate(templateFile, templateLanguage); if (templateFilePath != null) { var parentId = parentNode.GetHierarchyId(); var result = new VSADDRESULT[1]; _projectVsServices.VsProject.AddItemWithSpecific(parentId, VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD, fileName, 0, new string[] { templateFilePath }, IntPtr.Zero, 0, Guid.Empty, null, Guid.Empty, result); if (result[0] == VSADDRESULT.ADDRESULT_Success) { return(true); } } return(false); }
private ProjectItem IncludeExistingFolder(string folderName, ProjectItems collection) { IVsHierarchy targetHierarchy = TargetProject.GetVsHierarchy(_solution); if (targetHierarchy is IVsProject targetIVsProject) { string folderAbsolutePath; if (collection.Parent is ProjectItem parentProjectItem) { folderAbsolutePath = Path.Combine(parentProjectItem.Properties.GetValue("FullPath", string.Empty), folderName); } else { folderAbsolutePath = Path.Combine(Path.GetDirectoryName(TargetProject.FullName), folderName); } string containerFolderRelativePath = GetPathRelativeToProject(TargetProject, Path.GetDirectoryName(folderAbsolutePath)); uint containerFolderId = _hierarchyHelper.GetItemId(targetHierarchy, containerFolderRelativePath); VSADDRESULT[] result = new VSADDRESULT[1]; int hr = targetIVsProject.AddItem(containerFolderId, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, string.Empty, //No file name because it's a directory 1, // Has to correspond to #items below... new[] { folderAbsolutePath }, // Full path to item IntPtr.Zero, // Don't show window result); // Result array... ErrorHandler.ThrowOnFailure(hr); _logger.Log(string.Format(CultureInfo.CurrentCulture, Resources.IncludingExistingFolderInProject, GetPathRelativeToProject(TargetProject, folderAbsolutePath), TargetProject.Name)); } return(collection.Item(folderName)); }
protected virtual ProjectItem EvaluateAddResult(VSADDRESULT result, string path) { return(ThreadHelper.JoinableTaskFactory.Run(async delegate { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (result == VSADDRESULT.ADDRESULT_Success) { HierarchyNode nodeAdded = this.NodeWithItems.FindChild(path); Debug.Assert(nodeAdded != null, "We should have been able to find the new element in the hierarchy"); if (nodeAdded != null) { ProjectItem item = null; if (nodeAdded is FileNode) { item = new OAFileItem(this.Project, nodeAdded as FileNode); } else if (nodeAdded is NestedProjectNode) { item = new OANestedProjectItem(this.Project, nodeAdded as NestedProjectNode); } else { item = new OAProjectItem <HierarchyNode>(this.Project, nodeAdded); } IEnumerable <ProjectItem> match = base.Items.Where((ProjectItem titem) => titem.Name == item.Name); if (match == null || match.Count() == 0) { base.Items.Add(item); } return item; } } return null; })); }
/// <summary> /// Adds an item to the project. /// </summary> /// <param name="path">The full path of the item to add.</param> /// <param name="op">The <paramref name="VSADDITEMOPERATION"/> to use when adding the item.</param> /// <returns>A ProjectItem object. </returns> protected virtual EnvDTE.ProjectItem AddItem(string path, VSADDITEMOPERATION op) { CheckProjectIsValid(); return(this.Project.ProjectNode.Site.GetUIThread().Invoke <EnvDTE.ProjectItem>(() => { var proj = this.Project.ProjectNode; EnvDTE.ProjectItem itemAdded = null; using (var scope = new AutomationScope(this.Project.ProjectNode.Site)) { var result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, path, 0, new string[1] { path }, IntPtr.Zero, result)); string realPath = null; if (op != VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE) { var fileName = Path.GetFileName(path); var fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); realPath = Path.Combine(fileDirectory, fileName); } else { realPath = path; } itemAdded = this.EvaluateAddResult(result[0], realPath); } return itemAdded; })); }
/// <summary> /// Evaluates the result of an add operation. /// </summary> /// <param name="result">The <paramref name="VSADDRESULT"/> returned by the Add methods</param> /// <param name="path">The full path of the item added.</param> /// <returns>A ProjectItem object.</returns> private EnvDTE.ProjectItem EvaluateAddResult(VSADDRESULT result, string path) { return(this.Project.ProjectNode.Site.GetUIThread().Invoke <EnvDTE.ProjectItem>(() => { if (result != VSADDRESULT.ADDRESULT_Failure) { if (Directory.Exists(path)) { path = CommonUtils.EnsureEndSeparator(path); } var nodeAdded = this.NodeWithItems.ProjectMgr.FindNodeByFullPath(path); Debug.Assert(nodeAdded != null, "We should have been able to find the new element in the hierarchy"); if (nodeAdded != null) { EnvDTE.ProjectItem item = null; if (nodeAdded is FileNode fileNode) { item = new OAFileItem(this.Project, fileNode); } else { item = new OAProjectItem(this.Project, nodeAdded); } return item; } } return null; })); }
/// <summary> /// Adds an item to the project. /// </summary> /// <param name="path">The full path of the item to add.</param> /// <param name="op">The <paramref name="VSADDITEMOPERATION"/> to use when adding the item.</param> /// <returns>A ProjectItem object. </returns> protected virtual ProjectItem AddItem(string path, VSADDITEMOPERATION op) { CheckProjectIsValid(); return(ThreadHelper.JoinableTaskFactory.Run(async delegate { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); ProjectNode proj = this.Project.Project; ProjectItem itemAdded = null; using (AutomationScope scope = new AutomationScope(this.Project.Project.Site)) { VSADDRESULT[] result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, path, 0, new string[1] { path }, IntPtr.Zero, result)); string fileName = System.IO.Path.GetFileName(path); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); string filePathInProject = System.IO.Path.Combine(fileDirectory, fileName); itemAdded = this.EvaluateAddResult(result[0], filePathInProject); } return itemAdded; })); }
/// <summary> /// Add an existing item (file/folder) to the project if it already exist in our storage. /// </summary> /// <param name="parentNode">Node to that this item to</param> /// <param name="name">Name of the item being added</param> /// <param name="targetPath">Path of the item being added</param> /// <returns>Node that was added</returns> protected virtual HierarchyNode AddNodeIfTargetExistInStorage(HierarchyNode parentNode, string name, string targetPath) { HierarchyNode newNode = parentNode; // If the file/directory exist, add a node for it if (File.Exists(targetPath)) { VSADDRESULT[] result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(this.AddItem(parentNode.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, name, 1, new string[] { targetPath }, IntPtr.Zero, result)); if (result[0] != VSADDRESULT.ADDRESULT_Success) { throw new ApplicationException(); } newNode = this.FindChild(targetPath); if (newNode == null) { throw new ApplicationException(); } } else if (Directory.Exists(targetPath)) { newNode = this.CreateFolderNodes(targetPath); } return(newNode); }
private EnvDTE.ProjectItem EvaluateAddResult(VSADDRESULT result, string path) { return(UIThread.Instance.RunSync <EnvDTE.ProjectItem>(() => { if (result == VSADDRESULT.ADDRESULT_Success) { if (Directory.Exists(path) && !CommonUtils.HasEndSeparator(path)) { path = path + Path.DirectorySeparatorChar; } HierarchyNode nodeAdded = this.NodeWithItems.ProjectMgr.FindNodeByFullPath(path); Debug.Assert(nodeAdded != null, "We should have been able to find the new element in the hierarchy"); if (nodeAdded != null) { EnvDTE.ProjectItem item = null; if (nodeAdded is FileNode) { item = new OAFileItem(this.Project, nodeAdded as FileNode); } else { item = new OAProjectItem(this.Project, nodeAdded); } return item; } } return null; })); }
/// <summary> /// Create a file with the given template file and add it to the parent node. /// </summary> /// <param name="templateFile">The name of the template zip file.</param> /// <param name="path">The path to the file to be created.</param> /// <returns>true if file is added successfully.</returns> public async Task <bool> CreateFileAsync(string templateFile, string path) { Requires.NotNull(templateFile, nameof(templateFile)); Requires.NotNullOrEmpty(path, nameof(path)); string directoryName = Path.GetDirectoryName(path); string fileName = Path.GetFileName(path); string?templateLanguage = await GetTemplateLanguageAsync(); if (string.IsNullOrEmpty(templateLanguage)) { return(false); } await _projectVsServices.ThreadingService.SwitchToUIThread(); string templateFilePath = ((Solution2)_dte.Value !.Solution).GetProjectItemTemplate(templateFile, templateLanguage); if (templateFilePath != null) { HierarchyId parentId = _projectVsServices.VsProject.GetHierarchyId(directoryName); var result = new VSADDRESULT[1]; string[] files = new string[] { templateFilePath }; _projectVsServices.VsProject.AddItemWithSpecific(parentId, VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD, fileName, (uint)files.Length, files, IntPtr.Zero, 0, Guid.Empty, null, Guid.Empty, result); if (result[0] == VSADDRESULT.ADDRESULT_Success) { return(true); } } return(false); }
/// <summary> /// Adds an item to the project. /// </summary> /// <param name="path">The full path of the item to add.</param> /// <param name="op">The <paramref name="VSADDITEMOPERATION"/> to use when adding the item.</param> /// <returns>A ProjectItem object. </returns> protected virtual EnvDTE.ProjectItem AddItem(string path, VSADDITEMOPERATION op) { if (this.Project == null || this.Project.Project == null || this.Project.Project.Site == null || this.Project.Project.IsClosed) { throw new InvalidOperationException(); } return(UIThread.DoOnUIThread(delegate() { ProjectNode proj = this.Project.Project; EnvDTE.ProjectItem itemAdded = null; using (AutomationScope scope = new AutomationScope(this.Project.Project.Site)) { VSADDRESULT[] result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, path, 0, new string[1] { path }, IntPtr.Zero, result)); string fileName = System.IO.Path.GetFileName(path); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); string filePathInProject = System.IO.Path.Combine(fileDirectory, fileName); itemAdded = this.EvaluateAddResult(result[0], filePathInProject); } return itemAdded; })); }
protected virtual EnvDTE.ProjectItem EvaluateAddResult(VSADDRESULT result, string path) { return(UIThread.DoOnUIThread(delegate() { if (result == VSADDRESULT.ADDRESULT_Success) { HierarchyNode nodeAdded = this.NodeWithItems.FindChild(path); Debug.Assert(nodeAdded != null, "We should have been able to find the new element in the hierarchy"); if (nodeAdded != null) { EnvDTE.ProjectItem item = null; if (nodeAdded is FileNode) { item = new OAFileItem(this.Project, nodeAdded as FileNode); } else if (nodeAdded is NestedProjectNode) { item = new OANestedProjectItem(this.Project, nodeAdded as NestedProjectNode); } else { item = new OAProjectItem <HierarchyNode>(this.Project, nodeAdded); } this.Items.Add(item); return item; } } return null; })); }
/// <summary> /// Create a file with the given template file and add it to the parent node. /// </summary> /// <param name="templateFile">The name of the template zip file.</param> /// <param name="parentNode">The node to which the new file will be added.</param> /// <param name="fileName">The name of the file to be created.</param> /// <returns>true if file is added successfully.</returns> public async Task <bool> CreateFileAsync(string templateFile, IProjectTree parentNode, string fileName) { Requires.NotNull(templateFile, nameof(templateFile)); Requires.NotNull(parentNode, nameof(parentNode)); Requires.NotNull(fileName, nameof(fileName)); await _projectVsServices.ThreadingService.SwitchToUIThread(); Project project = _projectVsServices.VsHierarchy.GetProperty <Project>(Shell.VsHierarchyPropID.ExtObject, null); var solution = project.DTE.Solution as Solution2; string templateFilePath = solution.GetProjectItemTemplate(templateFile, GetTemplateLanguage(project)); if (templateFilePath != null) { var parentId = parentNode.IsRoot() ? (uint)VSConstants.VSITEMID.Root : (uint)parentNode.Identity; var result = new VSADDRESULT[1]; _projectVsServices.VsProject.AddItemWithSpecific(parentId, VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD, fileName, 0, new string[] { templateFilePath }, IntPtr.Zero, 0, Guid.Empty, null, Guid.Empty, result); if (result[0] == VSADDRESULT.ADDRESULT_Success) { return(true); } } return(false); }
/// <summary> /// Adds one or more files to the solution folder. /// </summary> public async Task <IEnumerable <File> > AddExistingFilesAsync(params string[] files) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); IVsUIShell uiShell = await VS.Services.GetUIShellAsync(); uiShell.GetDialogOwnerHwnd(out IntPtr hwndDlgOwner); GetItemInfo(out IVsHierarchy hierarchy, out _, out _); Guid rguidEditorType = Guid.Empty, rguidLogicalView = Guid.Empty; VSADDRESULT[] result = new VSADDRESULT[1]; IVsProject3 project3 = (IVsProject3)hierarchy; project3.AddItemWithSpecific(itemidLoc: (uint)VSConstants.VSITEMID.Root, dwAddItemOperation: VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, pszItemName: "test", cFilesToOpen: (uint)files.Count(), //The name of the parameter is misleading, it's the number of files to process, //and whether to open in editor or not is determined by other flag rgpszFilesToOpen: files, hwndDlgOwner: hwndDlgOwner, grfEditorFlags: 0u, //We do not want to open in the editor rguidEditorType: ref rguidEditorType, pszPhysicalView: null, rguidLogicalView: ref rguidLogicalView, pResult: result); return(await File.FromFilesAsync(files)); }
/// <summary> /// Creates a new project item from an existing item template file and adds it to the project. /// </summary> /// <param name="fileName">The full path and file name of the template project file.</param> /// <param name="name">The file name to use for the new project item.</param> /// <returns>A ProjectItem object. </returns> public override EnvDTE.ProjectItem AddFromTemplate(string fileName, string name) { if (this.Project == null || this.Project.Project == null || this.Project.Project.Site == null || this.Project.Project.IsClosed) { throw new InvalidOperationException(); } return(UIThread.DoOnUIThread(delegate() { ProjectNode proj = this.Project.Project; EnvDTE.ProjectItem itemAdded = null; using (AutomationScope scope = new AutomationScope(this.Project.Project.Site)) { string fixedFileName = fileName; if (!File.Exists(fileName)) { string tempFileName = GetTemplateNoZip(fileName); if (File.Exists(tempFileName)) { fixedFileName = tempFileName; } } // Determine the operation based on the extension of the filename. // We should run the wizard only if the extension is vstemplate // otherwise it's a clone operation VSADDITEMOPERATION op; if (Utilities.IsTemplateFile(fixedFileName)) { op = VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD; } else { op = VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE; } VSADDRESULT[] result = new VSADDRESULT[1]; // It is not a very good idea to throw since the AddItem might return Cancel or Abort. // The problem is that up in the call stack the wizard code does not check whether it has received a ProjectItem or not and will crash. // The other problem is that we cannot get add wizard dialog back if a cancel or abort was returned because we throw and that code will never be executed. Typical catch 22. ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, name, 0, new string[1] { fixedFileName }, IntPtr.Zero, result)); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); string templateFilePath = System.IO.Path.Combine(fileDirectory, name); itemAdded = this.EvaluateAddResult(result[0], templateFilePath); } return itemAdded; })); }
/// <summary> /// Creates a new project item from an existing item template file and adds it to the project. /// </summary> /// <param name="fileName">The full path and file name of the template project file.</param> /// <param name="name">The file name to use for the new project item.</param> /// <returns>A ProjectItem object. </returns> public override EnvDTE.ProjectItem AddFromTemplate(string fileName, string name) { if (this.Project == null || this.Project.Project == null || this.Project.Project.Site == null || this.Project.Project.IsClosed) { throw new InvalidOperationException(); } ProjectNode proj = this.Project.Project; IVsExtensibility3 extensibility = this.Project.Project.Site.GetService(typeof(IVsExtensibility)) as IVsExtensibility3; if (extensibility == null) { throw new InvalidOperationException(); } EnvDTE.ProjectItem itemAdded = null; extensibility.EnterAutomationFunction(); try { // Determine the operation based on the extension of the filename. // We should run the wizard only if the extension is vstemplate // otherwise it's a clone operation VSADDITEMOPERATION op; if (Utilities.IsTemplateFile(fileName)) { op = VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD; } else { op = VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE; } VSADDRESULT[] result = new VSADDRESULT[1]; // It is not a very good idea to throw since the AddItem might return Cancel or Abort. // The problem is that up in the call stack the wizard code does not check whether it has received a ProjectItem or not and will crash. // The other problem is that we cannot get add wizard dialog back if a cancel or abort was returned because we throw and that code will never be executed. Typical catch 22. ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, name, 0, new string[1] { fileName }, IntPtr.Zero, result)); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); string templateFilePath = System.IO.Path.Combine(fileDirectory, name); itemAdded = this.EvaluateAddResult(result[0], templateFilePath); } finally { extensibility.ExitAutomationFunction(); } return itemAdded; }
public int AddItem(uint itemidLoc, VSADDITEMOPERATION dwAddItemOperation, string pszItemName, uint cFilesToOpen, string[] rgpszFilesToOpen, IntPtr hwndDlgOwner, VSADDRESULT[] pResult) { AddItemCalled = true; AddItemArgumentItemidLoc = itemidLoc; AddItemArgumentAddItemOperation = dwAddItemOperation; AddItemArgumentItemName = pszItemName; AddItemArgumentFilesToOpen = cFilesToOpen; AddItemArgumentArrayFilesToOpen = rgpszFilesToOpen; return VSConstants.S_OK; }
/// <summary> /// Process dataobject from Drag/Drop/Cut/Copy/Paste operation /// </summary> /// <remarks>The targetNode is set if the method is called from a drop operation, otherwise it is null</remarks> /// internal DropDataType ProcessSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode) { DropDataType dropDataType = DropDataType.None; bool isWindowsFormat = false; // Try to get it as a directory based project. List <string> filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSSTGPROJECTITEMS, dataObject, out dropDataType); if (filesDropped.Count == 0) { filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSREFPROJECTITEMS, dataObject, out dropDataType); } if (filesDropped.Count == 0) { filesDropped = DragDropHelper.GetDroppedFiles(NativeMethods.CF_HDROP, dataObject, out dropDataType); isWindowsFormat = (filesDropped.Count > 0); } if (dropDataType != DropDataType.None && filesDropped.Count > 0) { string[] filesDroppedAsArray = filesDropped.ToArray(); string sourceProjectPath = DragDropHelper.GetSourceProjectPath(dataObject); HierarchyNode node = (targetNode == null) ? this : targetNode; // For directory based projects the content of the clipboard is a double-NULL terminated list of Projref strings. if (isWindowsFormat) { // This is the code path when source is windows explorer VSADDRESULT[] vsaddresults = new VSADDRESULT[1]; vsaddresults[0] = VSADDRESULT.ADDRESULT_Failure; int addResult = AddItem(node.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, (uint)filesDropped.Count, filesDropped.ToArray(), IntPtr.Zero, vsaddresults); if (addResult != VSConstants.S_OK && addResult != VSConstants.S_FALSE && addResult != (int)OleConstants.OLECMDERR_E_CANCELED && vsaddresults[0] != VSADDRESULT.ADDRESULT_Success) { ErrorHandler.ThrowOnFailure(addResult); } return(dropDataType); } else { if (AddFilesFromProjectReferences(node, filesDroppedAsArray)) { return(dropDataType); } } } // If we reached this point then the drop data must be set to None. // Otherwise the OnPaste will be called with a valid DropData and that would actually delete the item. return(DropDataType.None); }
internal static void AddFileToProject(IVsProject vsProject, string parametersXmlPath) { string[] files = new string[1] { parametersXmlPath }; VSADDRESULT[] result = new VSADDRESULT[1]; vsProject.AddItem( VSConstants.VSITEMID_ROOT, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, parametersXmlPath, 1, files, IntPtr.Zero, result); }
private static async Task <bool> AddProjectItemsInBatchAsync(IVsHierarchy vsHierarchy, List <string> filePaths, Action <string, LogLevel> logAction, CancellationToken cancellationToken) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); IVsProjectBuildSystem bldSystem = vsHierarchy as IVsProjectBuildSystem; try { if (bldSystem != null) { bldSystem.StartBatchEdit(); } cancellationToken.ThrowIfCancellationRequested(); var vsProject = (IVsProject)vsHierarchy; VSADDRESULT[] result = new VSADDRESULT[filePaths.Count()]; vsProject.AddItem(VSConstants.VSITEMID_ROOT, VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE, string.Empty, (uint)filePaths.Count(), filePaths.ToArray(), IntPtr.Zero, result); foreach (string filePath in filePaths) { logAction.Invoke(string.Format(Resources.Text.LibraryAddedToProject, filePath.Replace('\\', '/')), LogLevel.Operation); } } catch (Exception ex) { Telemetry.TrackException(nameof(AddProjectItemsInBatchAsync), ex); return(false); } finally { if (bldSystem != null) { bldSystem.EndBatchEdit(); } } return(true); }
EnvDTE.ProjectItem AddItem(string path, VSADDITEMOPERATION op) { ProjectNode proj = this.project.project; VSADDRESULT[] result = new VSADDRESULT[1]; NativeMethods.ThrowOnFailure(proj.AddItem(node.ID, op, path, 0, new string[1] { path }, IntPtr.Zero, null)); if (result[0] == VSADDRESULT.ADDRESULT_Success) { HierarchyNode child = node.LastChild; EnvDTE.ProjectItem item = new OAProjectItem(this.project, child); this.items.Add(item); return(item); } return(null); }
/// <summary>Adds one or more files to the project.</summary> public static async Task AddFilesToProjectAsync(this Project project, params string[] files) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (project == null || project.IsKind(ProjectTypes.ASPNET_CORE) || project.IsKind(ProjectTypes.DOTNET_CORE) || project.IsKind(ProjectTypes.SSDT)) { return; } DTE2?dte = await VS.GetDTEAsync(); if (project.IsKind(ProjectTypes.WEBSITE)) { Command command = dte.Commands.Item("SolutionExplorer.Refresh"); if (command.IsAvailable) { dte.ExecuteCommand(command.Name); } return; } IVsSolution?solutionService = await VS.GetRequiredServiceAsync <SVsSolution, IVsSolution>(); solutionService.GetProjectOfUniqueName(project.UniqueName, out IVsHierarchy? hierarchy); if (hierarchy == null) { return; } var ip = (IVsProject)hierarchy; var result = new VSADDRESULT[files.Count()]; ip.AddItem(VSConstants.VSITEMID_ROOT, VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE, string.Empty, (uint)files.Count(), files.ToArray(), IntPtr.Zero, result); }
private static void CreateNewFile(NodejsProjectNode projectNode, uint containerId, string fileType) { using (var dialog = new NewFileNameForm(GetInitialName(fileType))) { if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { string itemName = dialog.TextBox.Text; VSADDRESULT[] pResult = new VSADDRESULT[1]; projectNode.AddItem( containerId, // Identifier of the container folder. VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE, // Indicate that we want to create this new file by cloning a template file. itemName, 1, // Number of templates in the next parameter. Must be 1 if using VSADDITEMOP_CLONEFILE. new string[] { Path.GetTempFileName() }, // Array contains the template file path. IntPtr.Zero, // Handle to the Add Item dialog box. Must be Zero if using VSADDITEMOP_CLONEFILE. pResult); } } }
/// <summary> /// Creates a new project item from an existing item template file and adds it to the project. /// </summary> /// <param name="fileName">The full path and file name of the template project file.</param> /// <param name="name">The file name to use for the new project item.</param> /// <returns>A ProjectItem object. </returns> public override EnvDTE.ProjectItem AddFromTemplate(string fileName, string name) { CheckProjectIsValid(); var proj = this.Project.ProjectNode; EnvDTE.ProjectItem itemAdded = null; using (var scope = new AutomationScope(this.Project.ProjectNode.Site)) { // Determine the operation based on the extension of the filename. // We should run the wizard only if the extension is vstemplate // otherwise it's a clone operation VSADDITEMOPERATION op; this.Project.ProjectNode.Site.GetUIThread().Invoke(() => { if (Utilities.IsTemplateFile(fileName)) { op = VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD; } else { op = VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE; } var result = new VSADDRESULT[1]; // It is not a very good idea to throw since the AddItem might return Cancel or Abort. // The problem is that up in the call stack the wizard code does not check whether it has received a ProjectItem or not and will crash. // The other problem is that we cannot get add wizard dialog back if a cancel or abort was returned because we throw and that code will never be executed. Typical catch 22. ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, name, 0, new string[1] { fileName }, IntPtr.Zero, result)); var fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); var templateFilePath = System.IO.Path.Combine(fileDirectory, name); itemAdded = this.EvaluateAddResult(result[0], templateFilePath); }); } return(itemAdded); }
public static void AddFilesToProject(this Project project, IEnumerable <string> files) { if (project == null || project.IsKind(ProjectTypes.ASPNET_5, ProjectTypes.DOTNET_Core, ProjectTypes.SSDT)) { return; } if (project.IsKind(ProjectTypes.WEBSITE_PROJECT)) { Command command = DTE.Commands.Item("SolutionExplorer.Refresh"); if (command.IsAvailable) { DTE.ExecuteCommand(command.Name); } return; } var solutionService = Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution; IVsHierarchy hierarchy = null; solutionService?.GetProjectOfUniqueName(project.UniqueName, out hierarchy); if (hierarchy == null) { return; } var ip = (IVsProject)hierarchy; VSADDRESULT[] result = new VSADDRESULT[files.Count()]; ip.AddItem(VSConstants.VSITEMID_ROOT, VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE, string.Empty, (uint)files.Count(), files.ToArray(), IntPtr.Zero, result); }
/// <summary> /// Creates a new project item from an existing item template file and adds it to the project. /// </summary> /// <param name="fileName">The full path and file name of the template project file.</param> /// <param name="name">The file name to use for the new project item.</param> /// <returns>A ProjectItem object. </returns> public override EnvDTE.ProjectItem AddFromTemplate(string fileName, string name) { if (this.Project == null || this.Project.Project == null || this.Project.Project.Site == null || this.Project.Project.IsClosed) { throw new InvalidOperationException(); } ProjectNode proj = this.Project.Project; IVsExtensibility3 extensibility = this.Project.Project.Site.GetService(typeof(IVsExtensibility)) as IVsExtensibility3; if (extensibility == null) { throw new InvalidOperationException(); } EnvDTE.ProjectItem itemAdded = null; extensibility.EnterAutomationFunction(); try { VSADDITEMOPERATION op = VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE; VSADDRESULT[] result = new VSADDRESULT[1]; // It is not a very good idea to throw since the AddItem might return Cancel or Abort. // The problem is that up in the call stack the wizard code does not check whether it has received a ProjectItem or not and will crash. // The other problem is that we cannot get add wizard dialog back if a cancel or abort was returned because we throw and that code will never be executed. Typical catch 22. ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, name, 0, new string[1] { fileName }, IntPtr.Zero, result)); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); string templateFilePath = System.IO.Path.Combine(fileDirectory, name); itemAdded = this.EvaluateAddResult(result[0], templateFilePath); } finally { extensibility.ExitAutomationFunction(); } return(itemAdded); }
public static void AddFilesToProject(this Project project, IEnumerable <string> files) { if (project == null || IsCapabilityMatch(project, Constants.DotNetCoreWebCapability)) { return; } if (project.IsKind(Constants.WebsiteProject)) { Command command = DTE.Commands.Item("SolutionExplorer.Refresh"); if (command.IsAvailable) { DTE.ExecuteCommand(command.Name); } return; } var solutionService = Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution; IVsHierarchy hierarchy = null; if (solutionService != null && !ErrorHandler.Failed(solutionService.GetProjectOfUniqueName(project.UniqueName, out hierarchy))) { if (hierarchy == null) { return; } var vsProject = (IVsProject)hierarchy; VSADDRESULT[] result = new VSADDRESULT[files.Count()]; vsProject.AddItem(VSConstants.VSITEMID_ROOT, VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE, string.Empty, (uint)files.Count(), files.ToArray(), IntPtr.Zero, result); } }
private static void CreateNewFile(NodejsProjectNode projectNode, uint containerId, string fileType) { using (var dialog = new NewFileNameForm(GetInitialName(fileType))) { if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { string itemName = dialog.TextBox.Text; VSADDRESULT[] pResult = new VSADDRESULT[1]; projectNode.AddItem( containerId, // Identifier of the container folder. VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE, // Indicate that we want to create this new file by cloning a template file. itemName, 1, // Number of templates in the next parameter. Must be 1 if using VSADDITEMOP_CLONEFILE. new string[] { GetTemplateFile(fileType) }, // Array contains the template file path. IntPtr.Zero, // Handle to the Add Item dialog box. Must be Zero if using VSADDITEMOP_CLONEFILE. pResult ); // TODO: Do we need to check if result[0] = VSADDRESULT.ADDRESULT_Success here? } } }
/// <summary> /// Add an existing item (file/folder) to the project if it already exist in our storage. /// </summary> /// <param name="parentNode">Node to that this item to</param> /// <param name="name">Name of the item being added</param> /// <param name="targetPath">Path of the item being added</param> /// <returns>Node that was added</returns> /*protected, but public for FSharp.Project.dll*/ public virtual HierarchyNode AddNodeIfTargetExistInStorage(HierarchyNode parentNode, string name, string targetPath) { HierarchyNode newNode = parentNode; // If the file/directory exist, add a node for it if (FSSafe.File.SafeExists(targetPath)) { VSADDRESULT[] result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(this.AddItem(parentNode.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, name, 1, new string[] { targetPath }, IntPtr.Zero, result)); if (result[0] != VSADDRESULT.ADDRESULT_Success) throw new ApplicationException(); newNode = this.FindChild(targetPath); if (newNode == null) throw new ApplicationException(); } else if (Directory.Exists(targetPath)) { newNode = this.CreateFolderNodes(targetPath); } return newNode; }
/// <summary> /// Adds an item to the project. /// </summary> /// <param name="path">The full path of the item to add.</param> /// <param name="op">The VSADDITEMOPERATION to use when adding the item.</param> /// <returns>A ProjectItem object. </returns> public virtual EnvDTE.ProjectItem AddItem(string path, VSADDITEMOPERATION op) { return(UIThread.DoOnUIThread(delegate() { if (this.Project == null || this.Project.Project == null || this.Project.Project.Site == null || this.Project.Project.IsClosed) { throw new InvalidOperationException(); } ProjectNode proj = this.Project.Project; IVsExtensibility3 extensibility = this.Project.Project.Site.GetService(typeof(IVsExtensibility)) as IVsExtensibility3; if (extensibility == null) { throw new InvalidOperationException(); } EnvDTE.ProjectItem itemAdded = null; extensibility.EnterAutomationFunction(); try { VSADDRESULT[] result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, path, 0, new string[1] { path }, IntPtr.Zero, result)); string fileName = System.IO.Path.GetFileName(path); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); string filePathInProject = System.IO.Path.Combine(fileDirectory, fileName); itemAdded = this.EvaluateAddResult(result[0], filePathInProject); } finally { extensibility.ExitAutomationFunction(); } return itemAdded; })); }
internal static void CreateNewFile(NodejsProjectNode projectNode, uint containerId) { using (var dialog = new NewFileNameForm("")) { if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { string itemName = dialog.TextBox.Text; if (string.IsNullOrWhiteSpace(itemName)) { return; } itemName = itemName.Trim(); VSADDRESULT[] pResult = new VSADDRESULT[1]; projectNode.AddItem( containerId, // Identifier of the container folder. VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE, // Indicate that we want to create this new file by cloning a template file. itemName, 1, // Number of templates in the next parameter. Must be 1 if using VSADDITEMOP_CLONEFILE. new string[] { Path.GetTempFileName() }, // Array contains the template file path. IntPtr.Zero, // Handle to the Add Item dialog box. Must be Zero if using VSADDITEMOP_CLONEFILE. pResult); } } }
private bool AddItem(SvnItem item, out uint parentId) { ThreadHelper.ThrowIfNotOnUIThread(); string itemDir = item.Directory; if (itemDir == null) { parentId = VSItemId.Nil; return(false); } else if (string.Equals(itemDir, ProjectDirectory, StringComparison.OrdinalIgnoreCase)) { parentId = VSItemId.Root; } else { parentId = GetId(itemDir, VSItemId.Root); if (parentId == VSItemId.Nil) { if (!AddItem(item.Parent, out parentId)) { return(false); } parentId = GetId(itemDir, parentId); if (parentId == VSItemId.Nil) { return(false); } } } VSADDRESULT[] result = new VSADDRESULT[1]; return(VSErr.Succeeded(VsProject.AddItem(parentId, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, item.FullPath, 1, new string[] { item.FullPath }, IntPtr.Zero, result)) && result[0] == VSADDRESULT.ADDRESULT_Success); }
/// <summary> /// Adds an item to the project. /// </summary> /// <param name="path">The full path of the item to add.</param> /// <param name="op">The <paramref name="VSADDITEMOPERATION"/> to use when adding the item.</param> /// <returns>A ProjectItem object. </returns> protected virtual EnvDTE.ProjectItem AddItem(string path, VSADDITEMOPERATION op) { CheckProjectIsValid(); return(UIThread.Instance.RunSync <EnvDTE.ProjectItem>(() => { string ext = Path.GetExtension(path); foreach (var extension in this.Project.ProjectNode.CodeFileExtensions) { // http://pytools.codeplex.com/workitem/617 // We are currently in create project from existing code mode. The wizard walks all of the top-level // files and adds them. It then lets us handle any subdirectories by calling AddFromDirectory. // But we want to filter the files for both top-level and subdirectories. Therefore we derive from // PageManager and track when we're running the wizard and adding files for the wizard. If we are // currently adding them ignore anything other than a .py/.pyw files - returnning null is fine // here, the wizard doesn't care about the result. if (String.Compare(ext, extension, StringComparison.OrdinalIgnoreCase) == 0) { ProjectNode proj = this.Project.ProjectNode; EnvDTE.ProjectItem itemAdded = null; using (AutomationScope scope = new AutomationScope(this.Project.ProjectNode.Site)) { VSADDRESULT[] result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, path, 0, new string[1] { path }, IntPtr.Zero, result)); string fileName = System.IO.Path.GetFileName(path); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); string filePathInProject = System.IO.Path.Combine(fileDirectory, fileName); itemAdded = this.EvaluateAddResult(result[0], filePathInProject); } return itemAdded; } } return null; })); }
public virtual int AddItem(uint itemIdLoc, VSADDITEMOPERATION op, string itemName, uint filesToOpen, string[] files, IntPtr dlgOwner, VSADDRESULT[] result) { Guid empty = Guid.Empty; return AddItemWithSpecific(itemIdLoc, op, itemName, filesToOpen, files, dlgOwner, 0, ref empty, null, ref empty, result); }
/// <summary> /// Creates a new project item from an existing item template file and adds it to the project. /// </summary> /// <param name="fileName">The full path and file name of the template project file.</param> /// <param name="name">The file name to use for the new project item.</param> /// <returns>A ProjectItem object. </returns> public override ProjectItem AddFromTemplate(string fileName, string name) { if (Project == null || Project.Project == null || Project.Project.Site == null || Project.Project.IsClosed) { throw new InvalidOperationException(); } return UIThread.DoOnUIThread(delegate { var proj = Project.Project; ProjectItem itemAdded = null; using (var scope = new AutomationScope(Project.Project.Site)) { var fixedFileName = fileName; if (!File.Exists(fileName)) { var tempFileName = GetTemplateNoZip(fileName); if (File.Exists(tempFileName)) { fixedFileName = tempFileName; } } // Determine the operation based on the extension of the filename. // We should run the wizard only if the extension is vstemplate // otherwise it's a clone operation VSADDITEMOPERATION op; if (Utilities.IsTemplateFile(fixedFileName)) { op = VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD; } else { op = VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE; } var result = new VSADDRESULT[1]; // It is not a very good idea to throw since the AddItem might return Cancel or Abort. // The problem is that up in the call stack the wizard code does not check whether it has received a ProjectItem or not and will crash. // The other problem is that we cannot get add wizard dialog back if a cancel or abort was returned because we throw and that code will never be executed. Typical catch 22. ErrorHandler.ThrowOnFailure(proj.AddItem(NodeWithItems.ID, op, name, 0, new string[1] {fixedFileName}, IntPtr.Zero, result)); var fileDirectory = proj.GetBaseDirectoryForAddingFiles(NodeWithItems); var templateFilePath = Path.Combine(fileDirectory, name); itemAdded = EvaluateAddResult(result[0], templateFilePath); } return itemAdded; }); }
// ================= Drag/Drop/Cut/Copy/Paste ======================== // Ported from HeirUtil7\PrjHeir.cpp void ProcessSelectionDataObject(Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, uint grfKeyState, out DropDataType pddt){ pddt = DropDataType.None; // try HDROP FORMATETC fmtetc = DragDropHelper.CreateFormatEtc(CF_HDROP); bool hasData = false; try{ DragDropHelper.QueryGetData(pDataObject, ref fmtetc); hasData = true; } catch (Exception){ } if (hasData){ try{ STGMEDIUM stgmedium = DragDropHelper.GetData(pDataObject, ref fmtetc); if (stgmedium.tymed == (uint)TYMED.TYMED_HGLOBAL){ IntPtr hDropInfo = stgmedium.unionmember; if (hDropInfo != IntPtr.Zero){ pddt = DropDataType.Shell; try{ uint numFiles = DragQueryFile(hDropInfo, 0xFFFFFFFF, null, 0); char[] szMoniker = new char[MAX_PATH + 1]; IVsProject vsProj = (IVsProject)this.projectMgr; for (uint iFile = 0; iFile < numFiles; iFile++){ uint len = DragQueryFile(hDropInfo, iFile, szMoniker, MAX_PATH); string filename = new String(szMoniker, 0, (int)len); // Is full path returned if (File.Exists(filename)){ VSADDRESULT[] vsaddresult = new VSADDRESULT[1]; vsaddresult[0] = VSADDRESULT.ADDRESULT_Failure; string[] files = new String[1]{ filename }; // TODO: support dropping into subfolders... vsProj.AddItem(this.projectMgr.hierarchyId, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, 1, files, IntPtr.Zero, vsaddresult); } } Marshal.FreeHGlobal(hDropInfo); } catch (Exception e){ Marshal.FreeHGlobal(hDropInfo); throw e; } } } return; } catch (Exception){ hasData = false; } } if (DragDropHelper.AttemptVsFormat(this, DragDropHelper.CF_VSREFPROJECTITEMS, pDataObject, grfKeyState, out pddt)) return; if (DragDropHelper.AttemptVsFormat(this, DragDropHelper.CF_VSSTGPROJECTITEMS, pDataObject, grfKeyState, out pddt)) return; }
public int AddItem(uint itemidLoc, VSADDITEMOPERATION dwAddItemOperation, string pszItemName, uint cFilesToOpen, string[] rgpszFilesToOpen, IntPtr hwndDlgOwner, VSADDRESULT[] pResult) { throw new Exception("The method or operation is not implemented."); }
/// <summary> /// Process dataobject from Drag/Drop/Cut/Copy/Paste operation /// </summary> /// <remarks>The targetNode is set if the method is called from a drop operation, otherwise it is null</remarks> internal DropDataType ProcessSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode, uint grfKeyState) { DropDataType dropDataType = DropDataType.None; bool isWindowsFormat = false; // Try to get it as a directory based project. List<string> filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSSTGPROJECTITEMS, dataObject, out dropDataType); if (filesDropped.Count == 0) { filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSREFPROJECTITEMS, dataObject, out dropDataType); } if (filesDropped.Count == 0) { filesDropped = DragDropHelper.GetDroppedFiles(NativeMethods.CF_HDROP, dataObject, out dropDataType); isWindowsFormat = (filesDropped.Count > 0); } dropItems.Clear(); if (dropDataType != DropDataType.None && filesDropped.Count > 0) { bool saveAllowDuplicateLinks = this.AllowDuplicateLinks; try { DropEffect dropEffect = this.QueryDropEffect(dropDataType, grfKeyState); this.dropAsCopy = dropEffect == DropEffect.Copy; if (dropEffect == DropEffect.Move && this.SourceDraggedOrCutOrCopied) { // Temporarily allow duplicate links to enable cut-paste or drag-move of links within the project. // This won't happen when the source is another project because this.SourceDraggedOrCutOrCopied won't get set. this.AllowDuplicateLinks = true; } string[] filesDroppedAsArray = filesDropped.ToArray(); HierarchyNode node = (targetNode == null) ? this : targetNode; // For directory based projects the content of the clipboard is a double-NULL terminated list of Projref strings. if (isWindowsFormat) { // This is the code path when source is windows explorer VSADDRESULT[] vsaddresults = new VSADDRESULT[1]; vsaddresults[0] = VSADDRESULT.ADDRESULT_Failure; int addResult = AddItem(node.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, (uint)filesDropped.Count, filesDroppedAsArray, IntPtr.Zero, vsaddresults); if (addResult != VSConstants.S_OK && addResult != VSConstants.S_FALSE && addResult != (int)OleConstants.OLECMDERR_E_CANCELED && vsaddresults[0] != VSADDRESULT.ADDRESULT_Success) { ErrorHandler.ThrowOnFailure(addResult); } return dropDataType; } else { if (AddFilesFromProjectReferences(node, filesDroppedAsArray, (uint)dropEffect)) { return dropDataType; } } } finally { this.AllowDuplicateLinks = saveAllowDuplicateLinks; } } this.dataWasCut = false; // If we reached this point then the drop data must be set to None. // Otherwise the OnPaste will be called with a valid DropData and that would actually delete the item. return DropDataType.None; }
/// <summary> /// Adds an item from a project refererence to target node. /// </summary> /// <param name="projectRef"></param> /// <param name="targetNode"></param> private bool AddFileToNodeFromProjectReference(string projectRef, HierarchyNode targetNode) { if (String.IsNullOrEmpty(projectRef)) { throw new ArgumentException(SR.GetString(SR.ParameterCannotBeNullOrEmpty, CultureInfo.CurrentUICulture), "projectRef"); } if (targetNode == null) { throw new ArgumentNullException("targetNode"); } IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution; if (solution == null) { throw new InvalidOperationException(); } uint itemidLoc; IVsHierarchy hierarchy; string str; VSUPDATEPROJREFREASON[] reason = new VSUPDATEPROJREFREASON[1]; ErrorHandler.ThrowOnFailure(solution.GetItemOfProjref(projectRef, out hierarchy, out itemidLoc, out str, reason)); if (hierarchy == null) { throw new InvalidOperationException(); } // This will throw invalid cast exception if the hierrachy is not a project. IVsProject project = (IVsProject)hierarchy; string moniker; ErrorHandler.ThrowOnFailure(project.GetMkDocument(itemidLoc, out moniker)); string[] files = new String[1] { moniker }; VSADDRESULT[] vsaddresult = new VSADDRESULT[1]; vsaddresult[0] = VSADDRESULT.ADDRESULT_Failure; int addResult = targetNode.ProjectMgr.DoAddItem(targetNode.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, 0, files, IntPtr.Zero, vsaddresult, AddItemContext.Paste); if (addResult != VSConstants.S_OK && addResult != VSConstants.S_FALSE && addResult != (int)OleConstants.OLECMDERR_E_CANCELED) { ErrorHandler.ThrowOnFailure(addResult); return false; } return (vsaddresult[0] == VSADDRESULT.ADDRESULT_Success); }
/// <summary> /// Adds an item to the project. /// </summary> /// <param name="path">The full path of the item to add.</param> /// <param name="op">The <paramref name="VSADDITEMOPERATION" /> to use when adding the item.</param> /// <returns>A ProjectItem object. </returns> protected virtual ProjectItem AddItem(string path, VSADDITEMOPERATION op) { if (Project == null || Project.Project == null || Project.Project.Site == null || Project.Project.IsClosed) { throw new InvalidOperationException(); } return UIThread.DoOnUIThread(delegate { var proj = Project.Project; ProjectItem itemAdded = null; using (var scope = new AutomationScope(Project.Project.Site)) { var result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(proj.AddItem(NodeWithItems.ID, op, path, 0, new string[1] {path}, IntPtr.Zero, result)); var fileName = Path.GetFileName(path); var fileDirectory = proj.GetBaseDirectoryForAddingFiles(NodeWithItems); var filePathInProject = Path.Combine(fileDirectory, fileName); itemAdded = EvaluateAddResult(result[0], filePathInProject); } return itemAdded; }); }
/// <summary> /// Adds an item to the project. /// </summary> /// <param name="path">The full path of the item to add.</param> /// <param name="op">The <paramref name="VSADDITEMOPERATION"/> to use when adding the item.</param> /// <returns>A ProjectItem object. </returns> protected virtual EnvDTE.ProjectItem AddItem(string path, VSADDITEMOPERATION op) { if (this.Project == null || this.Project.Project == null || this.Project.Project.Site == null || this.Project.Project.IsClosed) { throw new InvalidOperationException(); } ProjectNode proj = this.Project.Project; IVsExtensibility3 extensibility = this.Project.Project.Site.GetService(typeof(IVsExtensibility)) as IVsExtensibility3; if (extensibility == null) { throw new InvalidOperationException(); } EnvDTE.ProjectItem itemAdded = null; extensibility.EnterAutomationFunction(); try { VSADDRESULT[] result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, path, 0, new string[1] { path }, IntPtr.Zero, result)); string fileName = System.IO.Path.GetFileName(path); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); string filePathInProject = System.IO.Path.Combine(fileDirectory, fileName); itemAdded = this.EvaluateAddResult(result[0], filePathInProject); } finally { extensibility.ExitAutomationFunction(); } return itemAdded; }
/// <summary> /// Renames the file in the hierarchy by removing old node and adding a new node in the hierarchy. /// </summary> /// <param name="oldFileName">The old file name.</param> /// <param name="newFileName">The new file name</param> /// <param name="newParentId">The new parent id of the item.</param> /// <returns>The newly added FileNode.</returns> /// <remarks>While a new node will be used to represent the item, the underlying MSBuild item will be the same and as a result file properties saved in the project file will not be lost.</remarks> protected virtual FileNode RenameFileNode(string oldFileName, string newFileName, uint newParentId) { if(string.Compare(oldFileName, newFileName, StringComparison.Ordinal) == 0) { // We do not want to rename the same file return null; } this.OnItemDeleted(); this.Parent.RemoveChild(this); // Since this node has been removed all of its state is zombied at this point // Do not call virtual methods after this point since the object is in a deleted state. string[] file = new string[1]; file[0] = newFileName; VSADDRESULT[] result = new VSADDRESULT[1]; Guid emptyGuid = Guid.Empty; ErrorHandler.ThrowOnFailure(this.ProjectMgr.AddItemWithSpecific(newParentId, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, 0, file, IntPtr.Zero, 0, ref emptyGuid, null, ref emptyGuid, result)); FileNode childAdded = this.ProjectMgr.FindChild(newFileName) as FileNode; Debug.Assert(childAdded != null, "Could not find the renamed item in the hierarchy"); // Update the itemid to the newly added. this.ID = childAdded.ID; // Remove the item created by the add item. We need to do this otherwise we will have two items. // Please be aware that we have not removed the ItemNode associated to the removed file node from the hierrachy. // What we want to achieve here is to reuse the existing build item. // We want to link to the newly created node to the existing item node and addd the new include. //temporarily keep properties from new itemnode since we are going to overwrite it string newInclude = childAdded.ItemNode.Item.EvaluatedInclude; string dependentOf = childAdded.ItemNode.GetMetadata(ProjectFileConstants.DependentUpon); childAdded.ItemNode.RemoveFromProjectFile(); // Assign existing msbuild item to the new childnode childAdded.ItemNode = this.ItemNode; childAdded.ItemNode.Item.ItemType = this.ItemNode.ItemName; childAdded.ItemNode.Item.Xml.Include = newInclude; if(!string.IsNullOrEmpty(dependentOf)) childAdded.ItemNode.SetMetadata(ProjectFileConstants.DependentUpon, dependentOf); childAdded.ItemNode.RefreshProperties(); //Update the new document in the RDT. DocumentManager.RenameDocument(this.ProjectMgr.Site, oldFileName, newFileName, childAdded.ID); //Select the new node in the hierarchy IVsUIHierarchyWindow uiWindow = UIHierarchyUtilities.GetUIHierarchyWindow(this.ProjectMgr.Site, SolutionExplorer); // This happens in the context of renaming a file. // Since we are already in solution explorer, it is extremely unlikely that we get a null return. // If we do, the consequences are minimal: the parent node will be selected instead of the // renamed node. if (uiWindow != null) { ErrorHandler.ThrowOnFailure(uiWindow.ExpandItem(this.ProjectMgr, this.ID, EXPANDFLAGS.EXPF_SelectItem)); } //Update FirstChild childAdded.FirstChild = this.FirstChild; //Update ChildNodes SetNewParentOnChildNodes(childAdded); RenameChildNodes(childAdded); return childAdded; }
/// <summary> /// Adds an item to the project. /// </summary> /// <param name="path">The full path of the item to add.</param> /// <param name="op">The <paramref name="VSADDITEMOPERATION"/> to use when adding the item.</param> /// <returns>A ProjectItem object. </returns> protected virtual EnvDTE.ProjectItem AddItem(string path, VSADDITEMOPERATION op) { if(this.Project == null || this.Project.Project == null || this.Project.Project.Site == null || this.Project.Project.IsClosed) { throw new InvalidOperationException(); } return UIThread.DoOnUIThread(delegate() { ProjectNode proj = this.Project.Project; EnvDTE.ProjectItem itemAdded = null; using (AutomationScope scope = new AutomationScope(this.Project.Project.Site)) { VSADDRESULT[] result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, path, 0, new string[1] { path }, IntPtr.Zero, result)); string fileName = System.IO.Path.GetFileName(path); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); string filePathInProject = System.IO.Path.Combine(fileDirectory, fileName); itemAdded = this.EvaluateAddResult(result[0], filePathInProject); } return itemAdded; }); }
/// <include file='doc\VsShellUtilities.uex' path='docs/doc[@for="VsShellUtilities.OpenAsMiscellaneousFile"]/*' /> /// <devdoc> /// Open a file using the miscellaneous project. /// </devdoc> /// <param name="provider">The service provider.</param> /// <param name="path">Path to the item to open.</param> /// <param name="caption">Caption of the item.</param> /// <param name="editor">Unique identifier of the editor type.</param> /// <param name="physicalView">Name of physical view.</param> /// <param name="logicalView">Name of logical view.</param> public static void OpenAsMiscellaneousFile(IServiceProvider provider, string path, string caption, Guid editor, string physicalView, Guid logicalView) { if (provider == null) { throw new ArgumentException("provider"); } if (String.IsNullOrEmpty(path)) { throw new ArgumentException("path"); } IVsProject3 proj = VsShellUtilities.GetMiscellaneousProject(provider); VSADDRESULT[] result = new VSADDRESULT[1]; // NOTE: This method must use VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE. // VSADDITEMOPERATION.VSADDITEMOP_OPENFILE doesn't work. VSADDITEMOPERATION op = VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE; __VSCREATEEDITORFLAGS flags = __VSCREATEEDITORFLAGS.CEF_CLONEFILE; ErrorHandler.ThrowOnFailure(proj.AddItemWithSpecific(VSConstants.VSITEMID_NIL, op, caption, 1, new string[1] { path }, IntPtr.Zero, (uint)flags, ref editor, physicalView, ref logicalView, result)); if (result[0] != VSADDRESULT.ADDRESULT_Success) { throw new ApplicationException(result[0].ToString()); } }
internal void DropFilesOrFolders(string[] filesDropped, HierarchyNode ontoNode) { var waitDialog = (IVsThreadedWaitDialog)Site.GetService(typeof(SVsThreadedWaitDialog)); int waitResult = waitDialog.StartWaitDialog( "Adding files and folders...", "Adding files to your project, this may take several seconds...", null, 0, null, null ); try { ontoNode = ontoNode.GetDragTargetHandlerNode(); string nodePath = ontoNode.FullPathToChildren; bool droppingExistingDirectory = true; foreach (var droppedFile in filesDropped) { if (!Directory.Exists(droppedFile) || !String.Equals(Path.GetDirectoryName(droppedFile), nodePath, StringComparison.OrdinalIgnoreCase)) { droppingExistingDirectory = false; break; } } if (droppingExistingDirectory) { // we're dragging a directory/directories that already exist // into the location where they exist, we can do this via a fast path, // and pop up a nice progress bar. AddExistingDirectories(ontoNode, filesDropped); } else { foreach (var droppedFile in filesDropped) { if (Directory.Exists(droppedFile) && CommonUtils.IsSubpathOf(droppedFile, nodePath)) { int cancelled = 0; waitDialog.EndWaitDialog(ref cancelled); waitResult = VSConstants.E_FAIL; // don't end twice Utilities.ShowMessageBox( Site, SR.GetString(SR.CannotAddFolderAsDescendantOfSelf, CommonUtils.GetFileOrDirectoryName(droppedFile)), null, OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); return; } } // This is the code path when source is windows explorer VSADDRESULT[] vsaddresults = new VSADDRESULT[1]; vsaddresults[0] = VSADDRESULT.ADDRESULT_Failure; int addResult = AddItem(ontoNode.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, (uint)filesDropped.Length, filesDropped, IntPtr.Zero, vsaddresults); if (addResult != VSConstants.S_OK && addResult != VSConstants.S_FALSE && addResult != (int)OleConstants.OLECMDERR_E_CANCELED && vsaddresults[0] != VSADDRESULT.ADDRESULT_Success) { ErrorHandler.ThrowOnFailure(addResult); } } } finally { if (ErrorHandler.Succeeded(waitResult)) { int cancelled = 0; waitDialog.EndWaitDialog(ref cancelled); } } }
public virtual int AddItemWithSpecific(uint itemIdLoc, VSADDITEMOPERATION op, string itemName, uint filesToOpen, string[] files, IntPtr dlgOwner, uint editorFlags, ref Guid editorType, string physicalView, ref Guid logicalView, VSADDRESULT[] result) { if (files == null || result == null || files.Length == 0 || result.Length == 0) { return VSConstants.E_INVALIDARG; } // Locate the node to be the container node for the file(s) being added // only projectnode or foldernode and file nodes are valid container nodes // We need to locate the parent since the item wizard expects the parent to be passed. HierarchyNode n = this.NodeFromItemId(itemIdLoc); if (n == null) { return VSConstants.E_INVALIDARG; } while ((!(n is ProjectNode)) && (!(n is FolderNode)) && (!this.CanFileNodesHaveChilds || !(n is FileNode))) { n = n.Parent; } Debug.Assert(n != null, "We should at this point have either a ProjectNode or FolderNode or a FileNode as a container for the new filenodes"); // handle link and runwizard operations at this point switch (op) { case VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE: // we do not support this right now throw new NotImplementedException("VSADDITEMOP_LINKTOFILE"); case VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD: result[0] = this.RunWizard(n, itemName, files[0], dlgOwner); return VSConstants.S_OK; } string[] actualFiles = new string[files.Length]; VSQUERYADDFILEFLAGS[] flags = this.GetQueryAddFileFlags(files); string baseDir = this.GetBaseDirectoryForAddingFiles(n); // If we did not get a directory for node that is the parent of the item then fail. if (String.IsNullOrEmpty(baseDir)) { return VSConstants.E_FAIL; } // Pre-calculates some paths that we can use when calling CanAddItems List<string> filesToAdd = new List<string>(); for (int index = 0; index < files.Length; index++) { string newFileName = String.Empty; string file = files[index]; switch (op) { case VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE: { string fileName = Path.GetFileName(itemName); newFileName = Path.Combine(baseDir, fileName); } break; case VSADDITEMOPERATION.VSADDITEMOP_OPENFILE: { string fileName = Path.GetFileName(file); newFileName = Path.Combine(baseDir, fileName); } break; } filesToAdd.Add(newFileName); } // Ask tracker objects if we can add files if (!this.tracker.CanAddItems(filesToAdd.ToArray(), flags)) { // We were not allowed to add the files return VSConstants.E_FAIL; } if (!this.ProjectMgr.QueryEditProjectFile(false)) { throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED); } // Add the files to the hierarchy int actualFilesAddedIndex = 0; for (int index = 0; index < filesToAdd.Count; index++) { HierarchyNode child; bool overwrite = false; string newFileName = filesToAdd[index]; string file = files[index]; result[0] = VSADDRESULT.ADDRESULT_Failure; child = this.FindChild(newFileName); if (child != null) { // If the file to be added is an existing file part of the hierarchy then continue. if (NativeMethods.IsSamePath(file, newFileName)) { result[0] = VSADDRESULT.ADDRESULT_Cancel; continue; } int canOverWriteExistingItem = this.CanOverwriteExistingItem(file, newFileName); if (canOverWriteExistingItem == (int)OleConstants.OLECMDERR_E_CANCELED) { result[0] = VSADDRESULT.ADDRESULT_Cancel; return canOverWriteExistingItem; } else if (canOverWriteExistingItem == VSConstants.S_OK) { overwrite = true; } else { return canOverWriteExistingItem; } } // If the file to be added is not in the same path copy it. if (NativeMethods.IsSamePath(file, newFileName) == false) { if (!overwrite && File.Exists(newFileName)) { string message = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FileAlreadyExists, CultureInfo.CurrentUICulture), newFileName); string title = string.Empty; OLEMSGICON icon = OLEMSGICON.OLEMSGICON_QUERY; OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_YESNO; OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST; int messageboxResult = VsShellUtilities.ShowMessageBox(this.Site, title, message, icon, buttons, defaultButton); if (messageboxResult == NativeMethods.IDNO) { result[0] = VSADDRESULT.ADDRESULT_Cancel; return (int)OleConstants.OLECMDERR_E_CANCELED; } } // Copy the file to the correct location. // We will suppress the file change events to be triggered to this item, since we are going to copy over the existing file and thus we will trigger a file change event. // We do not want the filechange event to ocur in this case, similar that we do not want a file change event to occur when saving a file. IVsFileChangeEx fileChange = this.site.GetService(typeof(SVsFileChangeEx)) as IVsFileChangeEx; if (fileChange == null) { throw new InvalidOperationException(); } try { ErrorHandler.ThrowOnFailure(fileChange.IgnoreFile(VSConstants.VSCOOKIE_NIL, newFileName, 1)); if (op == VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE) { this.AddFileFromTemplate(file, newFileName); } else { PackageUtilities.CopyUrlToLocal(new Uri(file), newFileName); } } finally { ErrorHandler.ThrowOnFailure(fileChange.IgnoreFile(VSConstants.VSCOOKIE_NIL, newFileName, 0)); } } if (overwrite) { this.OverwriteExistingItem(child); } else { //Add new filenode/dependentfilenode this.AddNewFileNodeToHierarchy(n, newFileName); } result[0] = VSADDRESULT.ADDRESULT_Success; actualFiles[actualFilesAddedIndex++] = newFileName; } // Notify listeners that items were appended. if (actualFilesAddedIndex > 0) n.OnItemsAppended(n); //Open files if this was requested through the editorFlags bool openFiles = (editorFlags & (uint)__VSSPECIFICEDITORFLAGS.VSSPECIFICEDITOR_DoOpen) != 0; if (openFiles && actualFiles.Length <= filesToOpen) { for (int i = 0; i < filesToOpen; i++) { if (!String.IsNullOrEmpty(actualFiles[i])) { string name = actualFiles[i]; HierarchyNode child = this.FindChild(name); Debug.Assert(child != null, "We should have been able to find the new element in the hierarchy"); if (child != null) { IVsWindowFrame frame; if (editorType == Guid.Empty) { Guid view = Guid.Empty; ErrorHandler.ThrowOnFailure(this.OpenItem(child.ID, ref view, IntPtr.Zero, out frame)); } else { ErrorHandler.ThrowOnFailure(this.OpenItemWithSpecific(child.ID, editorFlags, ref editorType, physicalView, ref logicalView, IntPtr.Zero, out frame)); } // Show the window frame in the UI and make it the active window if (frame != null) { ErrorHandler.ThrowOnFailure(frame.Show()); } } } } } return VSConstants.S_OK; }
public int AddItem(uint itemidLoc, VSADDITEMOPERATION dwAddItemOperation, string pszItemName, uint cFilesToOpen, string[] rgpszFilesToOpen, IntPtr hwndDlgOwner, VSADDRESULT[] pResult) { // Check if we are adding an item to a folder that consists of browser-side code. // In this case, we will want to open the file with the default editor. var isClientCode = false; var project = _innerVsHierarchy.GetProject().GetNodejsProject(); var selectedItems = this.GetSelectedItems().GetEnumerator(); if (selectedItems.MoveNext()) { var currentId = selectedItems.Current.itemid; string name; GetCanonicalName(currentId, out name); var nodeFolderNode = project.FindNodeByFullPath(name) as NodejsFolderNode; if (nodeFolderNode != null) { if (nodeFolderNode.ContentType == FolderContentType.Browser) { isClientCode = true; } } } if (!isClientCode && _innerProject3 != null && IsJavaScriptFile(pszItemName)) { Guid ourEditor = IsES6IntellisensePreview() ? Guid.Empty : typeof(NodejsEditorFactory).GUID; Guid view = Guid.Empty; return _innerProject3.AddItemWithSpecific( itemidLoc, dwAddItemOperation, pszItemName, cFilesToOpen, rgpszFilesToOpen, hwndDlgOwner, dwAddItemOperation == VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE ? (uint)__VSSPECIFICEDITORFLAGS.VSSPECIFICEDITOR_DoOpen : 0, ref ourEditor, String.Empty, ref view, pResult ); } return _innerProject.AddItem(itemidLoc, dwAddItemOperation, pszItemName, cFilesToOpen, rgpszFilesToOpen, hwndDlgOwner, pResult); }
// (after dialog) Add existing item -> AdItemWithSpecific public override int AddItem(uint itemIdLoc, VSADDITEMOPERATION op, string itemName, uint filesToOpen, string[] files, IntPtr dlgOwner, VSADDRESULT[] result) { // Special MSBuild case: we invoked it directly instead of using the "add item" dialog. if (itemName != null && itemName.Equals("SimResult")) { SimResultsNode resultsNode = null; if (this.IsSimResultFilePresent()) resultsNode = this.FindChild("Results.sim") as SimResultsNode; if (resultsNode == null) { resultsNode = CreateAndAddSimResultsFile(); //TODO: what about save on project unload/exit? } var simulationTimestamp = DateTime.Now; bool filePresent = false; bool renameOutput = true; Boolean.TryParse(GetProjectProperty("RenameOutput"), out renameOutput); string baseOutputName = GetProjectProperty("BaseOutputName"); if (String.IsNullOrEmpty(baseOutputName)) { var msBuildProject = BlenXProjectPackage.MSBuildProjectFromIVsProject(this); foreach (Microsoft.Build.BuildEngine.BuildItem item in msBuildProject.EvaluatedItems) { if (item.Name.Equals(SimFiles.Prog.ToString())) { baseOutputName = item.Include; break; } } if (String.IsNullOrEmpty(baseOutputName)) baseOutputName = Path.GetFileNameWithoutExtension(this.ProjectFile) + ".prog"; } string newOutputName; if (renameOutput) { newOutputName = baseOutputName + simulationTimestamp.ToString("yyyy'-'MM'-'dd'-'HH'-'mm'-'ss"); // TODO: try to move! filePresent = TryCopy(baseOutputName, newOutputName, "spec"); TryCopy(baseOutputName, newOutputName, "E.out"); TryCopy(baseOutputName, newOutputName, "C.out"); TryCopy(baseOutputName, newOutputName, "V.out"); } else { newOutputName = baseOutputName; filePresent = File.Exists(this.ProjectFolder + Path.DirectorySeparatorChar + baseOutputName + ".spec"); } if (filePresent) { resultsNode.AddEntry(newOutputName, this.ProjectFolder, simulationTimestamp); } return VSConstants.S_OK; } // Add existing item: itemIdLoc = 4294967294, VSADDITEMOP_OPENFILE, itemName = null, files (filename), null, VSADDRESULT 1 (init with ADDRESULT_Failure) return base.AddItem(itemIdLoc, op, itemName, filesToOpen, files, dlgOwner, result); }
/// <summary> /// Process dataobject from Drag/Drop/Cut/Copy/Paste operation /// </summary> /// <remarks>The targetNode is set if the method is called from a drop operation, otherwise it is null</remarks> internal DropDataType ProcessSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode) { DropDataType dropDataType = DropDataType.None; bool isWindowsFormat = false; // Try to get it as a directory based project. List<string> filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSSTGPROJECTITEMS, dataObject, out dropDataType); if (filesDropped.Count == 0) { filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSREFPROJECTITEMS, dataObject, out dropDataType); } if (filesDropped.Count == 0) { filesDropped = DragDropHelper.GetDroppedFiles(NativeMethods.CF_HDROP, dataObject, out dropDataType); isWindowsFormat = (filesDropped.Count > 0); } if (dropDataType != DropDataType.None && filesDropped.Count > 0) { string[] filesDroppedAsArray = filesDropped.ToArray(); HierarchyNode node = (targetNode == null) ? this : targetNode; // For directory based projects the content of the clipboard is a double-NULL terminated list of Projref strings. if (isWindowsFormat) { // This is the code path when source is windows explorer VSADDRESULT[] vsaddresults = new VSADDRESULT[1]; vsaddresults[0] = VSADDRESULT.ADDRESULT_Failure; int addResult = AddItem(node.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, (uint)filesDropped.Count, filesDroppedAsArray, IntPtr.Zero, vsaddresults); if (addResult != VSConstants.S_OK && addResult != VSConstants.S_FALSE && addResult != (int)OleConstants.OLECMDERR_E_CANCELED && vsaddresults[0] != VSADDRESULT.ADDRESULT_Success) { ErrorHandler.ThrowOnFailure(addResult); } return dropDataType; } else { if (AddFilesFromProjectReferences(node, filesDroppedAsArray)) { return dropDataType; } } } // If we reached this point then the drop data must be set to None. // Otherwise the OnPaste will be called with a valid DropData and that would actually delete the item. return DropDataType.None; }
public override int AddItemWithSpecific(uint itemIdLoc, VSADDITEMOPERATION op, string itemName, uint filesToOpen, string[] files, IntPtr dlgOwner, uint editorFlags, ref Guid editorType, string physicalView, ref Guid logicalView, VSADDRESULT[] result) { //editor type? return base.AddItemWithSpecific(itemIdLoc, op, itemName, filesToOpen, files, dlgOwner, editorFlags, ref editorType, physicalView, ref logicalView, result); }
/// <summary> /// Adds an item to the project. /// </summary> /// <param name="path">The full path of the item to add.</param> /// <param name="op">The <paramref name="VSADDITEMOPERATION"/> to use when adding the item.</param> /// <returns>A ProjectItem object. </returns> protected virtual EnvDTE.ProjectItem AddItem(string path, VSADDITEMOPERATION op) { CheckProjectIsValid(); return Project.ProjectNode.Site.GetUIThread().Invoke<EnvDTE.ProjectItem>(() => { ProjectNode proj = this.Project.ProjectNode; EnvDTE.ProjectItem itemAdded = null; using (AutomationScope scope = new AutomationScope(this.Project.ProjectNode.Site)) { VSADDRESULT[] result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, path, 0, new string[1] { path }, IntPtr.Zero, result)); string realPath = null; if (op != VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE) { string fileName = Path.GetFileName(path); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); realPath = Path.Combine(fileDirectory, fileName); } else { realPath = path; } itemAdded = this.EvaluateAddResult(result[0], realPath); } return itemAdded; }); }
// This is for moving files from one part of our project to another. /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.AddFiles"]/*' /> public void AddFiles(string[] rgSrcFiles){ if (rgSrcFiles == null || rgSrcFiles.Length == 0) return; IVsSolution srpIVsSolution = this.GetService(typeof(IVsSolution)) as IVsSolution; if (srpIVsSolution == null) return; IVsProject ourProj = (IVsProject)this.projectMgr; foreach (string file in rgSrcFiles){ uint itemidLoc; IVsHierarchy srpIVsHierarchy; string str; VSUPDATEPROJREFREASON[] reason = new VSUPDATEPROJREFREASON[1]; srpIVsSolution.GetItemOfProjref(file, out srpIVsHierarchy, out itemidLoc, out str, reason); if (srpIVsHierarchy == null){ throw new InvalidOperationException();//E_UNEXPECTED; } IVsProject srpIVsProject = (IVsProject)srpIVsHierarchy; if (srpIVsProject == null){ continue; } string cbstrMoniker; srpIVsProject.GetMkDocument(itemidLoc, out cbstrMoniker); if (File.Exists(cbstrMoniker)){ string[] files = new String[1]{ cbstrMoniker }; VSADDRESULT[] vsaddresult = new VSADDRESULT[1]; vsaddresult[0] = VSADDRESULT.ADDRESULT_Failure; // bugbug: support dropping into subfolder. ourProj.AddItem(this.projectMgr.hierarchyId, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, 1, files, IntPtr.Zero, vsaddresult); if (vsaddresult[0] == VSADDRESULT.ADDRESULT_Cancel){ break; } } } }
protected virtual EnvDTE.ProjectItem EvaluateAddResult(VSADDRESULT result, string path) { return UIThread.DoOnUIThread(delegate() { if (result == VSADDRESULT.ADDRESULT_Success) { HierarchyNode nodeAdded = this.NodeWithItems.FindChild(path); Debug.Assert(nodeAdded != null, "We should have been able to find the new element in the hierarchy"); if (nodeAdded != null) { EnvDTE.ProjectItem item = null; if (nodeAdded is FileNode) { item = new OAFileItem(this.Project, nodeAdded as FileNode); } else if (nodeAdded is NestedProjectNode) { item = new OANestedProjectItem(this.Project, nodeAdded as NestedProjectNode); } else { item = new OAProjectItem<HierarchyNode>(this.Project, nodeAdded); } this.Items.Add(item); return item; } } return null; }); }
int IVsProject.AddItem(uint itemidLoc, VSADDITEMOPERATION dwAddItemOperation, string pszItemName, uint cFilesToOpen, string[] rgpszFilesToOpen, IntPtr hwndDlgOwner, VSADDRESULT[] pResult) { if (Directory.Exists(rgpszFilesToOpen[0])) { AddProject(new MockVSHierarchy(rgpszFilesToOpen[0], this)); } else { children.Add(rgpszFilesToOpen[0]); if (project != null) { FileInfo itemFileInfo = new FileInfo(rgpszFilesToOpen[0]); project.Save(fileName); FileInfo projectFileInfo = new FileInfo(project.FullFileName); string itemName = itemFileInfo.FullName.Substring(projectFileInfo.Directory.FullName.Length + 1); project.AddNewItem("Compile", itemName); project.Save(fileName); } } return VSConstants.S_OK; }
/// <summary> /// Creates a new project item from an existing item template file and adds it to the project. /// </summary> /// <param name="fileName">The full path and file name of the template project file.</param> /// <param name="name">The file name to use for the new project item.</param> /// <returns>A ProjectItem object. </returns> public override EnvDTE.ProjectItem AddFromTemplate(string fileName, string name) { CheckProjectIsValid(); ProjectNode proj = this.Project.ProjectNode; EnvDTE.ProjectItem itemAdded = null; using (AutomationScope scope = new AutomationScope(this.Project.ProjectNode.Site)) { // Determine the operation based on the extension of the filename. // We should run the wizard only if the extension is vstemplate // otherwise it's a clone operation VSADDITEMOPERATION op; Project.ProjectNode.Site.GetUIThread().Invoke(() => { if (Utilities.IsTemplateFile(fileName)) { op = VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD; } else { op = VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE; } VSADDRESULT[] result = new VSADDRESULT[1]; // It is not a very good idea to throw since the AddItem might return Cancel or Abort. // The problem is that up in the call stack the wizard code does not check whether it has received a ProjectItem or not and will crash. // The other problem is that we cannot get add wizard dialog back if a cancel or abort was returned because we throw and that code will never be executed. Typical catch 22. ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, name, 0, new string[1] { fileName }, IntPtr.Zero, result)); string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems); string templateFilePath = System.IO.Path.Combine(fileDirectory, name); itemAdded = this.EvaluateAddResult(result[0], templateFilePath); }); } return itemAdded; }
int IVsProject.AddItem(uint itemidLoc, VSADDITEMOPERATION dwAddItemOperation, string pszItemName, uint cFilesToOpen, string[] rgpszFilesToOpen, IntPtr hwndDlgOwner, VSADDRESULT[] pResult) { return _innerProject.AddItem(itemidLoc, dwAddItemOperation, pszItemName, cFilesToOpen, rgpszFilesToOpen, hwndDlgOwner, pResult); }
/// <summary> /// Evaluates the result of an add operation. /// </summary> /// <param name="result">The <paramref name="VSADDRESULT"/> returned by the Add methods</param> /// <param name="path">The full path of the item added.</param> /// <returns>A ProjectItem object.</returns> private EnvDTE.ProjectItem EvaluateAddResult(VSADDRESULT result, string path) { return Project.ProjectNode.Site.GetUIThread().Invoke<EnvDTE.ProjectItem>(() => { if (result != VSADDRESULT.ADDRESULT_Failure) { if (Directory.Exists(path)) { path = CommonUtils.EnsureEndSeparator(path); } HierarchyNode nodeAdded = this.NodeWithItems.ProjectMgr.FindNodeByFullPath(path); Debug.Assert(nodeAdded != null, "We should have been able to find the new element in the hierarchy"); if (nodeAdded != null) { EnvDTE.ProjectItem item = null; var fileNode = nodeAdded as FileNode; if (fileNode != null) { item = new OAFileItem(this.Project, fileNode); } else { item = new OAProjectItem(this.Project, nodeAdded); } return item; } } return null; }); }
/// <summary> /// Add an existing item (file/folder) to the project if it already exist in our storage. /// </summary> /// <param name="parentNode">Node to that this item to</param> /// <param name="name">Name of the item being added</param> /// <param name="targetPath">Path of the item being added</param> /// <returns>Node that was added</returns> protected virtual HierarchyNode AddNodeIfTargetExistInStorage(HierarchyNode parentNode, string name, string targetPath) { if (parentNode == null) { return null; } var newNode = parentNode; // If the file/directory exist, add a node for it if (File.Exists(targetPath)) { var result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(AddItem(parentNode.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, name, 1, new[] {targetPath}, IntPtr.Zero, result)); if (result[0] != VSADDRESULT.ADDRESULT_Success) throw new Exception(); newNode = FindChild(targetPath); if (newNode == null) throw new Exception(); } else if (Directory.Exists(targetPath)) { newNode = CreateFolderNodes(targetPath); } return newNode; }