Microsoft.VisualStudio.Project.ProjectNode.AddItemWithSpecific C# (CSharp) Method

AddItemWithSpecific() private method

private AddItemWithSpecific ( uint itemIdLoc, VSADDITEMOPERATION op, string itemName, uint filesToOpen, string files, IntPtr dlgOwner, uint editorFlags, Guid &editorType, string physicalView, Guid &logicalView, VSADDRESULT result ) : int
itemIdLoc uint
op VSADDITEMOPERATION
itemName string
filesToOpen uint
files string
dlgOwner IntPtr
editorFlags uint
editorType Guid
physicalView string
logicalView Guid
result VSADDRESULT
return int
        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;
        }
ProjectNode