Esempio n. 1
0
        /// <summary>
        /// Called to reload a project item.
        /// Reloads a project and its nested project nodes.
        /// </summary>
        /// <param name="itemId">Specifies itemid from VSITEMID.</param>
        /// <param name="reserved">Reserved.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code. </returns>
        public override int ReloadItem(uint itemId, uint reserved)
        {
            #region precondition
            if (this.IsClosed)
            {
                return(VSConstants.E_FAIL);
            }
            #endregion

            NestedProjectNode node = this.NodeFromItemId(itemId) as NestedProjectNode;

            if (node != null)
            {
                object propertyAsObject = node.GetProperty((int)__VSHPROPID.VSHPROPID_HandlesOwnReload);

                if (propertyAsObject != null && (bool)propertyAsObject)
                {
                    node.ReloadItem(reserved);
                }
                else
                {
                    this.ReloadNestedProjectNode(node);
                }

                return(VSConstants.S_OK);
            }

            return(base.ReloadItem(itemId, reserved));
        }
        /// <summary>
        /// This can be called directly or through RunVsTemplateWizard.
        /// This will clone a template project file and add it as a
        /// subproject to our hierarchy.
        /// If you want to create a project for which there exist a
        /// vstemplate, consider using RunVsTemplateWizard instead.
        /// </summary>
        protected internal virtual NestedProjectNode AddNestedProjectFromTemplate(string fileName, string destination, string projectName, ProjectElement element, __VSCREATEPROJFLAGS creationFlags)
        {
            // If this is project creation and the template specified a subproject in its project file, this.nestedProjectElement will be used
            ProjectElement elementToUse = (element == null) ? this.nestedProjectElement : element;

            if (elementToUse == null)
            {
                // If this is null, this means MSBuild does not know anything about our subproject so add an MSBuild item for it
                elementToUse = new ProjectElement(this, fileName, ProjectFileConstants.SubProject);
            }
            NestedProjectNode node = CreateNestedProjectNode(elementToUse);

            node.Init(fileName, destination, projectName, creationFlags);

            // Since Init computes the final path, set the MSBuild item to that path
            string relativePath = node.Url;

            if (Path.IsPathRooted(relativePath))
            {
                relativePath = this.ProjectFolder;
                if (!relativePath.EndsWith("/\\"))
                {
                    relativePath += Path.DirectorySeparatorChar;
                }
                relativePath = new Url(relativePath).MakeRelative(new Url(node.Url));
            }
            elementToUse.Rename(relativePath);

            this.AddChild(node);
            return(node);
        }
Esempio n. 3
0
 /// <summary>
 /// Links the nested project nodes to the solution. The default implementation parses all nested project nodes and calles AddVirtualProjectEx on them.
 /// </summary>
 protected virtual void AddVirtualProjects()
 {
     for (HierarchyNode child = this.FirstChild; child != null; child = child.NextSibling)
     {
         NestedProjectNode nestedProjectNode = child as NestedProjectNode;
         if (nestedProjectNode != null)
         {
             nestedProjectNode.AddVirtualProject();
         }
     }
 }
Esempio n. 4
0
        internal protected void RemoveNestedProjectNodes()
        {
            for (HierarchyNode n = this.FirstChild; n != null; n = n.NextSibling)
            {
                NestedProjectNode p = n as NestedProjectNode;
                if (p != null)
                {
                    p.CloseNestedProjectNode();
                }
            }

            // We do not care of file changes after this.
            this.NestedProjectNodeReloader.FileChangedOnDisk -= this.OnNestedProjectFileChangedOnDisk;
            this.NestedProjectNodeReloader.Dispose();
        }
Esempio n. 5
0
        /// <summary>
        /// Enumerates the nested hierachies that should be added to the build dependency list.
        /// </summary>
        /// <returns></returns>
        public virtual IVsHierarchy[] EnumNestedHierachiesForBuildDependency()
        {
            List <IVsHierarchy> nestedProjectList = new List <IVsHierarchy>();

            // Add all nested project among projectContainer child nodes
            for (HierarchyNode child = this.FirstChild; child != null; child = child.NextSibling)
            {
                NestedProjectNode nestedProjectNode = child as NestedProjectNode;
                if (nestedProjectNode != null)
                {
                    nestedProjectList.Add(nestedProjectNode.NestedHierarchy);
                }
            }

            return(nestedProjectList.ToArray());
        }
Esempio n. 6
0
        public override int GetNestedHierarchy(UInt32 itemId, ref Guid iidHierarchyNested, out IntPtr ppHierarchyNested, out uint pItemId)
        {
            pItemId           = VSConstants.VSITEMID_ROOT;
            ppHierarchyNested = IntPtr.Zero;
            if (this.FirstChild != null)
            {
                for (HierarchyNode n = this.FirstChild; n != null; n = n.NextSibling)
                {
                    if (n is NestedProjectNode && n.ID == itemId)
                    {
                        NestedProjectNode p = n as NestedProjectNode;

                        if (p.NestedHierarchy != null)
                        {
                            IntPtr iunknownPtr = IntPtr.Zero;
                            int    returnValue = VSConstants.S_OK;
                            try
                            {
                                iunknownPtr = Marshal.GetIUnknownForObject(p.NestedHierarchy);
                                Marshal.QueryInterface(iunknownPtr, ref iidHierarchyNested, out ppHierarchyNested);
                            }
                            catch (COMException e)
                            {
                                returnValue = e.ErrorCode;
                            }
                            finally
                            {
                                if (iunknownPtr != IntPtr.Zero)
                                {
                                    Marshal.Release(iunknownPtr);
                                }
                            }

                            return(returnValue);
                        }
                        break;
                    }
                }
            }

            return(VSConstants.E_FAIL);
        }
Esempio n. 7
0
        /// <summary>
        /// Reloads a nested project node by deleting it and readding it.
        /// </summary>
        /// <param name="node">The node to reload.</param>
        protected virtual void ReloadNestedProjectNode(NestedProjectNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution;

            if (solution == null)
            {
                throw new InvalidOperationException();
            }

            NestedProjectNode newNode = null;

            try
            {
                // (VS 2005 UPDATE) When deleting and re-adding the nested project,
                // we do not want SCC to see this as a delete and add operation.
                this.EventTriggeringFlag = ProjectNode.EventTriggering.DoNotTriggerTrackerEvents;

                // notify SolutionEvents listeners that we are about to add children
                IVsFireSolutionEvents fireSolutionEvents = solution as IVsFireSolutionEvents;

                if (fireSolutionEvents == null)
                {
                    throw new InvalidOperationException();
                }

                ErrorHandler.ThrowOnFailure(fireSolutionEvents.FireOnBeforeUnloadProject(node.NestedHierarchy));

                int isDirtyAsInt = 0;
                this.IsDirty(out isDirtyAsInt);

                bool isDirty = (isDirtyAsInt == 0) ? false : true;

                ProjectElement element = node.ItemNode;
                node.CloseNestedProjectNode();

                // Remove from the solution
                this.RemoveChild(node);

                // Now readd it
                try
                {
                    __VSCREATEPROJFLAGS flags = __VSCREATEPROJFLAGS.CPF_NOTINSLNEXPLR | __VSCREATEPROJFLAGS.CPF_SILENT | __VSCREATEPROJFLAGS.CPF_OPENFILE;
                    newNode = this.AddExistingNestedProject(element, flags);
                    newNode.AddVirtualProject();
                }
                catch (Exception e)
                {
                    // We get a System.Exception if anything failed, thus we have no choice but catch it.
                    // Exceptions are digested by VS. Show the error if not in automation.
                    if (!Utilities.IsInAutomationFunction(this.Site))
                    {
                        string          message       = (String.IsNullOrEmpty(e.Message)) ? SR.GetString(SR.NestedProjectFailedToReload, CultureInfo.CurrentUICulture) : e.Message;
                        string          title         = string.Empty;
                        OLEMSGICON      icon          = OLEMSGICON.OLEMSGICON_CRITICAL;
                        OLEMSGBUTTON    buttons       = OLEMSGBUTTON.OLEMSGBUTTON_OK;
                        OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
                        VsShellUtilities.ShowMessageBox(this.Site, title, message, icon, buttons, defaultButton);
                    }

                    // Do not digest exception. let the caller handle it. If in a later stage this exception is not digested then the above messagebox is not needed.
                    throw e;
                }

#if DEBUG
                IVsHierarchy nestedHierarchy;
                solution.GetProjectOfUniqueName(newNode.GetMkDocument(), out nestedHierarchy);
                Debug.Assert(nestedHierarchy != null && Utilities.IsSameComObject(nestedHierarchy, newNode.NestedHierarchy), "The nested hierrachy was not reloaded correctly.");
#endif
                this.SetProjectFileDirty(isDirty);

                fireSolutionEvents.FireOnAfterLoadProject(newNode.NestedHierarchy);
            }
            finally
            {
                // In this scenario the nested project failed to unload or reload the nested project. We will unload the whole project, otherwise the nested project is lost.
                // This is similar to the scenario when one wants to open a project and the nested project cannot be loaded because for example the project file has xml errors.
                // We should note that we rely here that if the unload fails then exceptions are not digested and are shown to the user.
                if (newNode == null || newNode.NestedHierarchy == null)
                {
                    solution.CloseSolutionElement((uint)__VSSLNCLOSEOPTIONS.SLNCLOSEOPT_UnloadProject | (uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, this, 0);
                }
                else
                {
                    this.EventTriggeringFlag = ProjectNode.EventTriggering.TriggerAll;
                }
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Reloads a nested project node by deleting it and readding it.
        /// </summary>
        /// <param name="node">The node to reload.</param>
        protected virtual void ReloadNestedProjectNode(NestedProjectNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution;

            if (solution == null)
            {
                throw new InvalidOperationException();
            }

            NestedProjectNode newNode = null;
            try
            {
                // (VS 2005 UPDATE) When deleting and re-adding the nested project,
                // we do not want SCC to see this as a delete and add operation.
                this.EventTriggeringFlag = ProjectNode.EventTriggering.DoNotTriggerTrackerEvents;

                // notify SolutionEvents listeners that we are about to add children
                IVsFireSolutionEvents fireSolutionEvents = solution as IVsFireSolutionEvents;

                if (fireSolutionEvents == null)
                {
                    throw new InvalidOperationException();
                }

                ErrorHandler.ThrowOnFailure(fireSolutionEvents.FireOnBeforeUnloadProject(node.NestedHierarchy));

                int isDirtyAsInt = 0;
                this.IsDirty(out isDirtyAsInt);

                bool isDirty = (isDirtyAsInt == 0) ? false : true;

                ProjectElement element = node.ItemNode;
                node.CloseNestedProjectNode();

                // Remove from the solution
                this.RemoveChild(node);

                // Now readd it
                try
                {
                    __VSCREATEPROJFLAGS flags = __VSCREATEPROJFLAGS.CPF_NOTINSLNEXPLR | __VSCREATEPROJFLAGS.CPF_SILENT | __VSCREATEPROJFLAGS.CPF_OPENFILE;
                    newNode = this.AddExistingNestedProject(element, flags);
                    newNode.AddVirtualProject();
                }
                catch (Exception e)
                {
                    // We get a System.Exception if anything failed, thus we have no choice but catch it.
                    // Exceptions are digested by VS. Show the error if not in automation.
                    if (!Utilities.IsInAutomationFunction(this.Site))
                    {
                        string message = (String.IsNullOrEmpty(e.Message)) ? SR.GetString(SR.NestedProjectFailedToReload, CultureInfo.CurrentUICulture) : e.Message;
                        string title = string.Empty;
                        OLEMSGICON icon = OLEMSGICON.OLEMSGICON_CRITICAL;
                        OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_OK;
                        OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
                        VsShellUtilities.ShowMessageBox(this.Site, title, message, icon, buttons, defaultButton);
                    }

                    // Do not digest exception. let the caller handle it. If in a later stage this exception is not digested then the above messagebox is not needed.
                    throw e;
                }

            #if DEBUG
                IVsHierarchy nestedHierarchy;
                solution.GetProjectOfUniqueName(newNode.GetMkDocument(), out nestedHierarchy);
                Debug.Assert(nestedHierarchy != null && Utilities.IsSameComObject(nestedHierarchy, newNode.NestedHierarchy), "The nested hierrachy was not reloaded correctly.");
            #endif
                this.SetProjectFileDirty(isDirty);

                fireSolutionEvents.FireOnAfterLoadProject(newNode.NestedHierarchy);
            }
            finally
            {
                // In this scenario the nested project failed to unload or reload the nested project. We will unload the whole project, otherwise the nested project is lost.
                // This is similar to the scenario when one wants to open a project and the nested project cannot be loaded because for example the project file has xml errors.
                // We should note that we rely here that if the unload fails then exceptions are not digested and are shown to the user.
                if (newNode == null || newNode.NestedHierarchy == null)
                {
                    solution.CloseSolutionElement((uint)__VSSLNCLOSEOPTIONS.SLNCLOSEOPT_UnloadProject | (uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, this, 0);
                }
                else
                {
                    this.EventTriggeringFlag = ProjectNode.EventTriggering.TriggerAll;
                }
            }
        }