public virtual int OpenChildren() { IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution; Debug.Assert(solution != null, "Could not retrieve the solution from the services provided by this project"); if (solution == null) { return(VSConstants.E_FAIL); } IntPtr iUnKnownForSolution = IntPtr.Zero; int returnValue = VSConstants.S_OK; // be optimistic. try { this.DisableQueryEdit = true; this.EventTriggeringFlag = ProjectNode.EventTriggering.DoNotTriggerHierarchyEvents | ProjectNode.EventTriggering.DoNotTriggerTrackerEvents; iUnKnownForSolution = Marshal.GetIUnknownForObject(solution); // notify SolutionEvents listeners that we are about to add children IVsFireSolutionEvents fireSolutionEvents = Marshal.GetTypedObjectForIUnknown(iUnKnownForSolution, typeof(IVsFireSolutionEvents)) as IVsFireSolutionEvents; ErrorHandler.ThrowOnFailure(fireSolutionEvents.FireOnBeforeOpeningChildren(this)); this.AddVirtualProjects(); ErrorHandler.ThrowOnFailure(fireSolutionEvents.FireOnAfterOpeningChildren(this)); } catch (Exception e) { // Exceptions are digested by the caller but we want then to be shown if not a ComException and if not in automation. if (!(e is COMException) && !Utilities.IsInAutomationFunction(this.Site)) { string title = null; OLEMSGICON icon = OLEMSGICON.OLEMSGICON_CRITICAL; OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_OK; OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST; VsShellUtilities.ShowMessageBox(this.Site, title, e.Message, icon, buttons, defaultButton); } Trace.WriteLine("Exception : " + e.Message); throw; } finally { this.DisableQueryEdit = false; if (iUnKnownForSolution != IntPtr.Zero) { Marshal.Release(iUnKnownForSolution); } this.EventTriggeringFlag = ProjectNode.EventTriggering.TriggerAll; } return(returnValue); }
public virtual int CloseChildren() { int returnValue = VSConstants.S_OK; // be optimistic. ThreadHelper.ThrowIfNotOnUIThread(); IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution; Debug.Assert(solution != null, "Could not retrieve the solution from the services provided by this project"); if (solution == null) { return(VSConstants.E_FAIL); } IntPtr iUnKnownForSolution = IntPtr.Zero; try { iUnKnownForSolution = Marshal.GetIUnknownForObject(solution); // notify SolutionEvents listeners that we are about to close children IVsFireSolutionEvents fireSolutionEvents = Marshal.GetTypedObjectForIUnknown(iUnKnownForSolution, typeof(IVsFireSolutionEvents)) as IVsFireSolutionEvents; ErrorHandler.ThrowOnFailure(fireSolutionEvents.FireOnBeforeClosingChildren(this)); // If the removal crashes we never fire the close children event. IS that a problem? this.RemoveNestedProjectNodes(); ErrorHandler.ThrowOnFailure(fireSolutionEvents.FireOnAfterClosingChildren(this)); } finally { if (iUnKnownForSolution != IntPtr.Zero) { Marshal.Release(iUnKnownForSolution); } } return(returnValue); }
/// <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; } #if DEBUG IVsHierarchy nestedHierarchy; ErrorHandler.ThrowOnFailure(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); ErrorHandler.ThrowOnFailure(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) { ErrorHandler.ThrowOnFailure(solution.CloseSolutionElement((uint)__VSSLNCLOSEOPTIONS.SLNCLOSEOPT_UnloadProject | (uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, this, 0)); } else { this.EventTriggeringFlag = ProjectNode.EventTriggering.TriggerAll; } } }