/// <summary> /// This is used when loading the project to loop through all the items /// and for each SubProject it finds, it create the project and a node /// in our Hierarchy to hold the project. /// </summary> internal protected void CreateNestedProjectNodes() { // 1. Create a ProjectElement with the found item and then Instantiate a new Nested project with this ProjectElement. // 2. Link into the hierarchy. // Read subprojects from from msbuildmodel __VSCREATEPROJFLAGS creationFlags = __VSCREATEPROJFLAGS.CPF_NOTINSLNEXPLR | __VSCREATEPROJFLAGS.CPF_SILENT; if (this.IsNewProject) { creationFlags |= __VSCREATEPROJFLAGS.CPF_CLONEFILE; } else { creationFlags |= __VSCREATEPROJFLAGS.CPF_OPENFILE; } ThreadHelper.ThrowIfNotOnUIThread(); foreach (MSBuild.ProjectItem item in this.BuildProject.Items) { if (String.Compare(item.ItemType, ProjectFileConstants.SubProject, StringComparison.OrdinalIgnoreCase) == 0) { this.nestedProjectElement = new ProjectElement(this, item, false); if (!this.IsNewProject) { AddExistingNestedProject(null, creationFlags); } else { // If we are creating the subproject from a vstemplate/vsz file bool isVsTemplate = Utilities.IsTemplateFile(GetProjectTemplatePath(null)); if (isVsTemplate) { RunVsTemplateWizard(null, true); } else { // We are cloning the specified project file AddNestedProjectFromTemplate(null, creationFlags); } } } } this.nestedProjectElement = null; }
/// <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; } } }
/// <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); // In case that with did not have an existing element, or the nestedProjectelement was null // and since Init computes the final path, set the MSBuild item to that path if (this.nestedProjectElement == null) { string relativePath = node.Url; if (Path.IsPathRooted(relativePath)) { relativePath = this.ProjectFolder; if (!relativePath.EndsWith("/\\", StringComparison.Ordinal)) { relativePath += Path.DirectorySeparatorChar; } relativePath = new Url(relativePath).MakeRelative(new Url(node.Url)); } elementToUse.Rename(relativePath); } this.AddChild(node); return(node); }
/// <summary> /// 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(ProjectElement element, __VSCREATEPROJFLAGS creationFlags) { ProjectElement elementToUse = (element == null) ? this.nestedProjectElement : element; if (elementToUse == null) { throw new ArgumentNullException("element"); } string destination = elementToUse.GetFullPathForElement(); string template = this.GetProjectTemplatePath(elementToUse); return(this.AddNestedProjectFromTemplate(template, Path.GetDirectoryName(destination), Path.GetFileName(destination), elementToUse, creationFlags)); }
/// <summary> /// Add an existing project as a nested node of our hierarchy. /// This is used while loading the project and can also be used /// to add an existing project to our hierarchy. /// </summary> protected internal virtual NestedProjectNode AddExistingNestedProject(ProjectElement element, __VSCREATEPROJFLAGS creationFlags) { ProjectElement elementToUse = (element == null) ? this.nestedProjectElement : element; if (elementToUse == null) { throw new ArgumentNullException("element"); } string filename = elementToUse.GetFullPathForElement(); // Delegate to AddNestedProjectFromTemplate. Because we pass flags that specify open project rather then clone, this will works. Debug.Assert((creationFlags & __VSCREATEPROJFLAGS.CPF_OPENFILE) == __VSCREATEPROJFLAGS.CPF_OPENFILE, "__VSCREATEPROJFLAGS.CPF_OPENFILE should have been specified, did you mean to call AddNestedProjectFromTemplate?"); return(AddNestedProjectFromTemplate(filename, Path.GetDirectoryName(filename), Path.GetFileName(filename), elementToUse, creationFlags)); }
/// <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> public 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); // In case that with did not have an existing element, or the nestedProjectelement was null // and since Init computes the final path, set the MSBuild item to that path if(this.nestedProjectElement == null) { string relativePath = node.Url; if(Path.IsPathRooted(relativePath)) { relativePath = this.ProjectFolder; if(!relativePath.EndsWith("/\\", StringComparison.Ordinal)) { relativePath += Path.DirectorySeparatorChar; } relativePath = new Url(relativePath).MakeRelative(new Url(node.Url)); } elementToUse.Rename(relativePath); } this.AddChild(node); return node; }
/// <summary> /// 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> public virtual NestedProjectNode AddNestedProjectFromTemplate(ProjectElement element, __VSCREATEPROJFLAGS creationFlags) { ProjectElement elementToUse = (element == null) ? this.nestedProjectElement : element; if(elementToUse == null) { throw new ArgumentNullException("element"); } string destination = elementToUse.GetFullPathForElement(); string template = this.GetProjectTemplatePath(elementToUse); return this.AddNestedProjectFromTemplate(template, Path.GetDirectoryName(destination), Path.GetFileName(destination), elementToUse, creationFlags); }
/// <summary> /// Add an existing project as a nested node of our hierarchy. /// This is used while loading the project and can also be used /// to add an existing project to our hierarchy. /// </summary> public virtual NestedProjectNode AddExistingNestedProject(ProjectElement element, __VSCREATEPROJFLAGS creationFlags) { ProjectElement elementToUse = (element == null) ? this.nestedProjectElement : element; if(elementToUse == null) { throw new ArgumentNullException("element"); } string filename = elementToUse.GetFullPathForElement(); // Delegate to AddNestedProjectFromTemplate. Because we pass flags that specify open project rather then clone, this will works. Debug.Assert((creationFlags & __VSCREATEPROJFLAGS.CPF_OPENFILE) == __VSCREATEPROJFLAGS.CPF_OPENFILE, "__VSCREATEPROJFLAGS.CPF_OPENFILE should have been specified, did you mean to call AddNestedProjectFromTemplate?"); return AddNestedProjectFromTemplate(filename, Path.GetDirectoryName(filename), Path.GetFileName(filename), elementToUse, creationFlags); }
/// <summary> /// Initialize the nested hierarhy node. /// </summary> /// <param name="fileNameParam">The file name of the nested project.</param> /// <param name="destinationParam">The location of the nested project.</param> /// <param name="projectNameParam">The name of the project.</param> /// <param name="createFlags">The nested project creation flags </param> /// <remarks>This methos should be called just after a NestedProjectNode object is created.</remarks> public virtual void Init(string fileNameParam, string destinationParam, string projectNameParam, __VSCREATEPROJFLAGS createFlags) { if (String.IsNullOrEmpty(fileNameParam)) { throw new ArgumentException(SR.GetString(SR.ParameterCannotBeNullOrEmpty, CultureInfo.CurrentUICulture), "fileNameParam"); } if (String.IsNullOrEmpty(destinationParam)) { throw new ArgumentException(SR.GetString(SR.ParameterCannotBeNullOrEmpty, CultureInfo.CurrentUICulture), "destinationParam"); } this.projectName = Path.GetFileName(fileNameParam); this.projectPath = Path.Combine(destinationParam, this.projectName); // get the IVsSolution interface from the global service provider IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution; Debug.Assert(solution != null, "Could not get the IVsSolution object from the services exposed by this project"); if (solution == null) { throw new InvalidOperationException(); } // Get the project type guid from project element string typeGuidString = this.ItemNode.GetMetadataAndThrow(ProjectFileConstants.TypeGuid, new InvalidOperationException()); Guid projectFactoryGuid = Guid.Empty; if (!String.IsNullOrEmpty(typeGuidString)) { projectFactoryGuid = new Guid(typeGuidString); } // Get the project factory. IVsProjectFactory projectFactory; ErrorHandler.ThrowOnFailure(solution.GetProjectFactory((uint)0, new Guid[] { projectFactoryGuid }, fileNameParam, out projectFactory)); this.CreateProjectDirectory(); //Create new project using factory int cancelled; Guid refiid = NativeMethods.IID_IUnknown; IntPtr projectPtr = IntPtr.Zero; // For a nested project the creation at unsafe location is governed by the parent project since the nested project will end up in the cone of the parent project. bool dontShowAgain = DontShowAgainDialog.ReadDontShowAgainValue(ProjectFactory.DontShowProjectSecurityWarningAgain); try { DontShowAgainDialog.WriteDontShowAgainValue(ProjectFactory.DontShowProjectSecurityWarningAgain, 1); ErrorHandler.ThrowOnFailure(projectFactory.CreateProject(fileNameParam, destinationParam, projectNameParam, (uint)createFlags, ref refiid, out projectPtr, out cancelled)); if (projectPtr != IntPtr.Zero) { this.nestedHierarchy = Marshal.GetTypedObjectForIUnknown(projectPtr, typeof(IVsHierarchy)) as IVsHierarchy; Debug.Assert(this.nestedHierarchy != null, "Nested hierarchy could not be created"); Debug.Assert(cancelled == 0); } } finally { if (projectPtr != IntPtr.Zero) { // We created a new instance of the project, we need to call release to decrement the ref count // the RCW (this.nestedHierarchy) still has a reference to it which will keep it alive Marshal.Release(projectPtr); } // Revert back the old value that security questions about unsafe location are stil asked if that was the value. if (!dontShowAgain) { DontShowAgainDialog.WriteDontShowAgainValue(ProjectFactory.DontShowProjectSecurityWarningAgain, 0); } } if (cancelled != 0 && this.nestedHierarchy == null) { ErrorHandler.ThrowOnFailure(VSConstants.OLE_E_PROMPTSAVECANCELLED); } // Link into the nested VS hierarchy. ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ParentHierarchy, this.ProjectMgr)); ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ParentHierarchyItemid, (object)(int)this.ID)); this.LockRDTEntry(); this.ConnectPropertyNotifySink(); }
/// <summary> /// Initialize the nested hierarhy node. /// </summary> /// <param name="fileName"></param> /// <param name="destination"></param> /// <param name="projectName"></param> /// <param name="createFlags">The nested project creation flags </param> /// <remarks>This methos should be called just after a NestedProjectNode object is created.</remarks> public virtual void Init(string fileName, string destination, string projectName, __VSCREATEPROJFLAGS createFlags) { if (String.IsNullOrEmpty(fileName)) { throw new ArgumentException(SR.GetString(SR.ParameterCannotBeNullOrEmpty), "fileName"); } if (String.IsNullOrEmpty(destination)) { throw new ArgumentException(SR.GetString(SR.ParameterCannotBeNullOrEmpty), "destination"); } this.projectName = Path.GetFileName(fileName); this.projectPath = Path.Combine(destination, this.projectName); // get the IVsSolution interface from the global service provider IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution; Debug.Assert(solution != null, "Could not get the IVsSolution object from the services exposed by this project"); if (solution == null) { throw new InvalidOperationException(); } // Get the project type guid from project element string typeGuidString = this.ItemNode.GetMetadataAndThrow(ProjectFileConstants.TypeGuid, new ApplicationException()); Guid projectFactoryGuid = Guid.Empty; if (!String.IsNullOrEmpty(typeGuidString)) { projectFactoryGuid = new Guid(typeGuidString); } // Get the project factory. IVsProjectFactory projectFactory; ErrorHandler.ThrowOnFailure(solution.GetProjectFactory((uint)0, new Guid[] { projectFactoryGuid }, fileName, out projectFactory)); this.CreateProjectDirectory(); //Create new project using factory int cancelled; Guid refiid = NativeMethods.IID_IUnknown; IntPtr projectPtr = IntPtr.Zero; try { ErrorHandler.ThrowOnFailure(projectFactory.CreateProject(fileName, destination, projectName, (uint)createFlags, ref refiid, out projectPtr, out cancelled)); this.nestedHierarchy = Marshal.GetTypedObjectForIUnknown(projectPtr, typeof(IVsHierarchy)) as IVsHierarchy; Debug.Assert(this.nestedHierarchy != null, "Nested hierarchy could not be created"); Debug.Assert(cancelled == 0); } finally { if (projectPtr != IntPtr.Zero) { // We created a new instance of the project, we need to call release to decrement the ref count // the RCW (this.nestedHierarchy) still has a reference to it which will keep it alive Marshal.Release(projectPtr); } } // Link into the nested VS hierarchy. ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ParentHierarchy, this.ProjectMgr)); ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ParentHierarchyItemid, (object)(int)this.ID)); this.LockRDTEntry(); }
/// <summary> /// Initialize the nested hierarhy node. /// </summary> /// <param name="fileNameParam">The file name of the nested project.</param> /// <param name="destinationParam">The location of the nested project.</param> /// <param name="projectNameParam">The name of the project.</param> /// <param name="createFlags">The nested project creation flags </param> /// <remarks>This methos should be called just after a NestedProjectNode object is created.</remarks> public virtual void Init(string fileNameParam, string destinationParam, string projectNameParam, __VSCREATEPROJFLAGS createFlags) { if (String.IsNullOrEmpty(fileNameParam)) { throw new ArgumentException(SR.GetString(SR.ParameterCannotBeNullOrEmpty, CultureInfo.CurrentUICulture), "fileNameParam"); } if (String.IsNullOrEmpty(destinationParam)) { throw new ArgumentException(SR.GetString(SR.ParameterCannotBeNullOrEmpty, CultureInfo.CurrentUICulture), "destinationParam"); } this.projectName = Path.GetFileName(fileNameParam); this.projectPath = Path.Combine(destinationParam, this.projectName); // get the IVsSolution interface from the global service provider IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution; Debug.Assert(solution != null, "Could not get the IVsSolution object from the services exposed by this project"); if (solution == null) { throw new InvalidOperationException(); } // Get the project type guid from project element string typeGuidString = this.ItemNode.GetMetadataAndThrow(ProjectFileConstants.TypeGuid, new InvalidOperationException()); Guid projectFactoryGuid = Guid.Empty; if (!String.IsNullOrEmpty(typeGuidString)) { projectFactoryGuid = new Guid(typeGuidString); } // Get the project factory. IVsProjectFactory projectFactory; ErrorHandler.ThrowOnFailure(solution.GetProjectFactory((uint)0, new Guid[] { projectFactoryGuid }, fileNameParam, out projectFactory)); this.CreateProjectDirectory(); //Create new project using factory int cancelled; Guid refiid = NativeMethods.IID_IUnknown; IntPtr projectPtr = IntPtr.Zero; try { ErrorHandler.ThrowOnFailure(projectFactory.CreateProject(fileNameParam, destinationParam, projectNameParam, (uint)createFlags, ref refiid, out projectPtr, out cancelled)); if (projectPtr != IntPtr.Zero) { this.nestedHierarchy = Marshal.GetTypedObjectForIUnknown(projectPtr, typeof(IVsHierarchy)) as IVsHierarchy; Debug.Assert(this.nestedHierarchy != null, "Nested hierarchy could not be created"); Debug.Assert(cancelled == 0); } } finally { if (projectPtr != IntPtr.Zero) { // We created a new instance of the project, we need to call release to decrement the ref count // the RCW (this.nestedHierarchy) still has a reference to it which will keep it alive Marshal.Release(projectPtr); } } if (cancelled != 0 && this.nestedHierarchy == null) { ErrorHandler.ThrowOnFailure(VSConstants.OLE_E_PROMPTSAVECANCELLED); } // Link into the nested VS hierarchy. ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ParentHierarchy, this.ProjectMgr)); ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ParentHierarchyItemid, (object)(int)this.ID)); this.LockRDTEntry(); this.ConnectPropertyNotifySink(); }
/// <summary> /// 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(ProjectElement element, __VSCREATEPROJFLAGS creationFlags) { var elementToUse = element == null ? nestedProjectElement : element; if (elementToUse == null) { throw new ArgumentNullException("element"); } var destination = elementToUse.GetFullPathForElement(); var template = GetProjectTemplatePath(elementToUse); return AddNestedProjectFromTemplate(template, Path.GetDirectoryName(destination), Path.GetFileName(destination), elementToUse, creationFlags); }
int IVsProjectFactory.CreateProject(string pszFilename, string pszLocation, string pszName, uint grfCreateFlags, ref Guid iidProject, out IntPtr ppvProject, out int pfCanceled) { IntPtr pUnk = IntPtr.Zero; pfCanceled = 0; ppvProject = IntPtr.Zero; bool loadedSuccessfully = false; try { Tracer.VerifyStringArgument(pszFilename, "pszFilename"); __VSCREATEPROJFLAGS createFlags = (__VSCREATEPROJFLAGS)grfCreateFlags; // Get the right version of the project serializer. ProjectSerializer serializer = this.CreateSerializer(pszFilename); // Do we need to suppress any load failures from being reported to the end user. serializer.SilentFailures = ((createFlags & __VSCREATEPROJFLAGS.CPF_SILENT) == __VSCREATEPROJFLAGS.CPF_SILENT); // Now we need to load the project, either from a template file or from an existing file. bool openExisting = ((createFlags & __VSCREATEPROJFLAGS.CPF_OPENFILE) == __VSCREATEPROJFLAGS.CPF_OPENFILE); bool openFromTemplate = ((createFlags & __VSCREATEPROJFLAGS.CPF_CLONEFILE) == __VSCREATEPROJFLAGS.CPF_CLONEFILE); Tracer.Assert((openExisting && !openFromTemplate) || (!openExisting && openFromTemplate), "The grfCreateFlags are incorrect. You can't have both opening existing and opening from template. Flags={0}", createFlags); if (openExisting) { Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "Attempting to load project: File name={0} Location={1} Name={2} GUID={3}.", pszFilename, pszLocation, pszName, iidProject.ToString("B").ToUpper(CultureInfo.InvariantCulture)); loadedSuccessfully = serializer.Load(pszFilename); if (loadedSuccessfully) { Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "Successfully loaded project '{0}'.", pszFilename); } else { Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "There were errors in loading project '{0}'.", pszFilename); } } else { Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "Attempting to create a new project from a template: File name={0} Location={1} Name={2} GUID={3}.", pszFilename, pszLocation, pszName, iidProject.ToString("B").ToUpper(CultureInfo.InvariantCulture)); Tracer.VerifyStringArgument(pszLocation, "pszLocation"); Tracer.VerifyStringArgument(pszName, "pszName"); string destinationFile = Path.Combine(pszLocation, pszName); loadedSuccessfully = serializer.LoadFromTemplate(pszFilename, destinationFile); if (loadedSuccessfully) { Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "Successfully loaded project '{0}'.", pszFilename); } else { Tracer.WriteLineInformation(classType, "IVsProjectFactory.CreateProject", "There were errors in loading project '{0}'.", pszFilename); } } if (loadedSuccessfully) { // Once we've loaded the project, we need to return the COM object that the environment is requesting. pUnk = Marshal.GetIUnknownForObject(serializer.Project); int hr = Marshal.QueryInterface(pUnk, ref iidProject, out ppvProject); Tracer.Assert(NativeMethods.Succeeded(hr), "Cannot get the requested project interface ({0}): returned {1}", iidProject.ToString("B").ToUpper(CultureInfo.InvariantCulture), hr); NativeMethods.ThrowOnFailure(hr); } } catch (Exception e) { Package.Instance.Context.NotifyInternalError(e.ToString()); } finally { if (pUnk != IntPtr.Zero) { Marshal.Release(pUnk); } } return(loadedSuccessfully ? NativeMethods.S_OK : NativeMethods.E_FAIL); }