Ejemplo n.º 1
0
		/// <summary>
		/// Constructor for IVSOutput2 implementation
		/// </summary>
		/// <param name="projectManager">Project that produce this output</param>
		/// <param name="outputAssembly">MSBuild generated item corresponding to the output assembly (by default, these would be of type MainAssembly</param>
		public Output(ProjectNode projectManager, ProjectElement outputAssembly)
		{
			if(projectManager == null)
				throw new ArgumentNullException("projectManager");
			if(outputAssembly == null)
				throw new ArgumentNullException("outputAssembly");

			project = projectManager;
			output = outputAssembly;
		}
		/// <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);
		}
		protected internal void RunVsTemplateWizard(ProjectElement element, bool silent)
		{
			ProjectElement elementToUse = (element == null) ? this.nestedProjectElement : element;

			if(elementToUse == null)
			{
				throw new ArgumentNullException("element");
			}
			this.nestedProjectElement = elementToUse;

			Automation.OAProject oaProject = GetAutomationObject() as Automation.OAProject;
			if(oaProject == null || oaProject.ProjectItems == null)
				throw new System.InvalidOperationException(SR.GetString(SR.InvalidAutomationObject, CultureInfo.CurrentUICulture));
			Debug.Assert(oaProject.Object != null, "The project automation object should have set the Object to the SolutionFolder");
			Automation.OASolutionFolder<ProjectContainerNode> folder = oaProject.Object as Automation.OASolutionFolder<ProjectContainerNode>;

			// Prepare the parameters to pass to RunWizardFile
			string destination = elementToUse.GetFullPathForElement();
			string template = this.GetProjectTemplatePath(elementToUse);

			object[] wizParams = new object[7];
			wizParams[0] = EnvDTE.Constants.vsWizardAddSubProject;
			wizParams[1] = Path.GetFileNameWithoutExtension(destination);
			wizParams[2] = oaProject.ProjectItems;
			wizParams[3] = Path.GetDirectoryName(destination);
			wizParams[4] = Path.GetFileNameWithoutExtension(destination);
			wizParams[5] = Path.GetDirectoryName(folder.DTE.FullName); //VS install dir
			wizParams[6] = silent;

			IVsDetermineWizardTrust wizardTrust = this.GetService(typeof(SVsDetermineWizardTrust)) as IVsDetermineWizardTrust;
			if(wizardTrust != null)
			{
				Guid guidProjectAdding = Guid.Empty;

				// In case of a project template an empty guid should be added as the guid parameter. See env\msenv\core\newtree.h IsTrustedTemplate method definition.
				ErrorHandler.ThrowOnFailure(wizardTrust.OnWizardInitiated(template, ref guidProjectAdding));
			}

			try
			{
				// Make the call to execute the wizard. This should cause AddNestedProjectFromTemplate to be
				// called back with the correct set of parameters.
				EnvDTE.IVsExtensibility extensibilityService = (EnvDTE.IVsExtensibility)GetService(typeof(EnvDTE.IVsExtensibility));
				EnvDTE.wizardResult result = extensibilityService.RunWizardFile(template, 0, ref wizParams);
				if(result == EnvDTE.wizardResult.wizardResultFailure)
					throw new COMException();
			}
			finally
			{
				if(wizardTrust != null)
				{
					ErrorHandler.ThrowOnFailure(wizardTrust.OnWizardCompleted());
				}
			}
		}
		/// <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);
		}
		protected virtual ReferenceNode CreateReferenceNode(string referenceType, ProjectElement element)
		{
			ReferenceNode node = null;
			if(referenceType == ProjectFileConstants.COMReference)
			{
				node = this.CreateComReferenceNode(element);
			}
			else if(referenceType == ProjectFileConstants.Reference)
			{
				node = this.CreateAssemblyReferenceNode(element);
			}
			else if(referenceType == ProjectFileConstants.ProjectReference)
			{
				node = this.CreateProjectReferenceNode(element);
			}

			return node;
		}
Ejemplo n.º 6
0
		protected virtual FolderNode VerifySubFolderExists(string path, HierarchyNode parent)
		{
			FolderNode folderNode = null;
			uint uiItemId;
			Url url = new Url(this.BaseURI, path);
			string strFullPath = url.AbsoluteUrl;
			// Folders end in our storage with a backslash, so add one...
			ErrorHandler.ThrowOnFailure(this.ParseCanonicalName(strFullPath, out uiItemId));
			if(uiItemId != 0)
			{
				Debug.Assert(this.NodeFromItemId(uiItemId) is FolderNode, "Not a FolderNode");
				folderNode = (FolderNode)this.NodeFromItemId(uiItemId);
			}

			if(folderNode == null)
			{
				// folder does not exist yet...
				// We could be in the process of loading so see if msbuild knows about it
				MSBuild.BuildItemGroup folders = buildProject.GetEvaluatedItemsByName(ProjectFileConstants.Folder);
				ProjectElement item = null;
				foreach(MSBuild.BuildItem folder in folders)
				{
					if(String.Compare(folder.FinalItemSpec.TrimEnd('\\'), path.TrimEnd('\\'), StringComparison.OrdinalIgnoreCase) == 0)
					{
						item = new ProjectElement(this, folder, false);
						break;
					}
				}
				// If MSBuild did not know about it, create a new one
				if(item == null)
					item = this.AddFolderToMsBuild(path);
				folderNode = this.CreateFolderNode(path, item);
				parent.AddChild(folderNode);
			}

			return folderNode;
		}
Ejemplo n.º 7
0
		/// <summary>
		/// Create a file node based on an msbuild item.
		/// </summary>
		/// <param name="item">msbuild item</param>
		/// <returns>FileNode added</returns>
		public virtual FileNode CreateFileNode(ProjectElement item)
		{
			return new FileNode(this, item);
		}
		/// <summary>
		/// Based on the Template and TypeGuid properties of the
		/// element, generate the full template path.
		/// 
		/// TypeGuid should be the Guid of a registered project factory.
		/// Template can be a full path, a project template (for projects
		/// that support VsTemplates) or a relative path (for other projects).
		/// </summary>
		protected virtual string GetProjectTemplatePath(ProjectElement element)
		{
			ProjectElement elementToUse = (element == null) ? this.nestedProjectElement : element;

			if(elementToUse == null)
			{
				throw new ArgumentNullException("element");
			}

			string templateFile = elementToUse.GetMetadata(ProjectFileConstants.Template);
			Debug.Assert(!String.IsNullOrEmpty(templateFile), "No template file has been specified in the template attribute in the project file");

			string fullPath = templateFile;
			if(!Path.IsPathRooted(templateFile))
			{
				RegisteredProjectType registeredProjectType = this.GetRegisteredProject(elementToUse);

				// This is not a full path
				Debug.Assert(registeredProjectType != null && (!String.IsNullOrEmpty(registeredProjectType.DefaultProjectExtensionValue) || !String.IsNullOrEmpty(registeredProjectType.WizardTemplatesDirValue)), " Registered wizard directory value not set in the registry.");

				// See if this specify a VsTemplate file
				fullPath = registeredProjectType.GetVsTemplateFile(templateFile);
				if(String.IsNullOrEmpty(fullPath))
				{
					// Default to using the WizardTemplateDir to calculate the absolute path
					fullPath = Path.Combine(registeredProjectType.WizardTemplatesDirValue, templateFile);
				}
			}

			return fullPath;
		}
Ejemplo n.º 9
0
		/// <summary>
		/// Constructor for the FileNode
		/// </summary>
		/// <param name="root">Root of the hierarchy</param>
		/// <param name="e">Associated project element</param>
		public FileNode(ProjectNode root, ProjectElement element)
			: base(root, element)
		{
			if(this.ProjectMgr.NodeHasDesigner(this.ItemNode.GetMetadata(ProjectFileConstants.Include)))
			{
				this.HasDesigner = true;
			}
		}
		public ProjectReferenceNode(ProjectNode root, ProjectElement element)
			: base(root, element)
		{
			this.referencedProjectRelativePath = this.ItemNode.GetMetadata(ProjectFileConstants.Include);
			Debug.Assert(!String.IsNullOrEmpty(this.referencedProjectRelativePath), "Could not retrive referenced project path form project file");

			string guidString = this.ItemNode.GetMetadata(ProjectFileConstants.Project);

			// Continue even if project setttings cannot be read.
			try
			{
				this.referencedProjectGuid = new Guid(guidString);

				this.buildDependency = new BuildDependency(this.ProjectMgr, this.referencedProjectGuid);
				this.ProjectMgr.AddBuildDependency(this.buildDependency);
			}
			finally
			{
				Debug.Assert(this.referencedProjectGuid != Guid.Empty, "Could not retrive referenced project guidproject file");

				this.referencedProjectName = this.ItemNode.GetMetadata(ProjectFileConstants.Name);

				Debug.Assert(!String.IsNullOrEmpty(this.referencedProjectName), "Could not retrive referenced project name form project file");
			}

			Uri uri = new Uri(this.ProjectMgr.BaseURI.Uri, this.referencedProjectRelativePath);

			if(uri != null)
			{
				this.referencedProjectFullPath = Microsoft.VisualStudio.Shell.Url.Unescape(uri.LocalPath, true);
			}
		}
		/// <summary>
		/// Constructor for the ReferenceNode
		/// </summary>
		public AssemblyReferenceNode(ProjectNode root, ProjectElement element)
			: base(root, element)
		{
			this.GetPathNameFromProjectFile();

			this.InitializeFileChangeEvents();

			string include = this.ItemNode.GetMetadata(ProjectFileConstants.Include);

			this.CreateFromAssemblyName(new System.Reflection.AssemblyName(include));
		}
		/// <summary>
		/// Creates a com reference node from the project element.
		/// </summary>
		protected virtual ComReferenceNode CreateComReferenceNode(ProjectElement reference)
		{
			return new ComReferenceNode(this.ProjectMgr, reference);
		}
		/// <summary>
		/// Creates an assembly refernce node from a project element.
		/// </summary>
		protected virtual AssemblyReferenceNode CreateAssemblyReferenceNode(ProjectElement element)
		{
			AssemblyReferenceNode node = null;
			try
			{
				node = new AssemblyReferenceNode(this.ProjectMgr, element);
			}
			catch(ArgumentNullException e)
			{
				Trace.WriteLine("Exception : " + e.Message);
			}
			catch(FileNotFoundException e)
			{
				Trace.WriteLine("Exception : " + e.Message);
			}
			catch(BadImageFormatException e)
			{
				Trace.WriteLine("Exception : " + e.Message);
			}
			catch(FileLoadException e)
			{
				Trace.WriteLine("Exception : " + e.Message);
			}
			catch(System.Security.SecurityException e)
			{
				Trace.WriteLine("Exception : " + e.Message);
			}

			return node;
		}
		/// <summary>
		/// Creates a project reference node given an existing project element.
		/// </summary>
		protected virtual ProjectReferenceNode CreateProjectReferenceNode(ProjectElement element)
		{
			return new ProjectReferenceNode(this.ProjectMgr, element);
		}
		/// <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;
		}
Ejemplo n.º 16
0
		/// <summary>
		/// constructor for the ReferenceNode
		/// </summary>
		protected ReferenceNode(ProjectNode root, ProjectElement element)
			: base(root, element)
		{
			this.ExcludeNodeFromScc = true;
		}
		/// <summary>
		/// Override this method if you want to provide your own type of nodes.
		/// This would be the case if you derive a class from NestedProjectNode
		/// </summary>
		protected virtual NestedProjectNode CreateNestedProjectNode(ProjectElement element)
		{
			return new NestedProjectNode(this, element);
		}
		/// <summary>
		/// Constructor for the DependentFileNode
		/// </summary>
		/// <param name="root">Root of the hierarchy</param>
		/// <param name="e">Associated project element</param>
		public DependentFileNode(ProjectNode root, ProjectElement element)
			: base(root, element)
		{
			this.HasParentNodeNameRelation = false;
		}
		/// <summary>
		/// Get information from the registry based for the project 
		/// factory corresponding to the TypeGuid of the element
		/// </summary>
		private RegisteredProjectType GetRegisteredProject(ProjectElement element)
		{
			ProjectElement elementToUse = (element == null) ? this.nestedProjectElement : element;

			if(elementToUse == null)
			{
				throw new ArgumentNullException("element");
			}

			// Get the project type guid from project elementToUse				
			string typeGuidString = elementToUse.GetMetadataAndThrow(ProjectFileConstants.TypeGuid, new Exception());
			Guid projectFactoryGuid = new Guid(typeGuidString);

			EnvDTE.DTE dte = this.ProjectMgr.Site.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
			Debug.Assert(dte != null, "Could not get the automation object from the services exposed by this project");

			if(dte == null)
				throw new InvalidOperationException();

			RegisteredProjectType registeredProjectType = RegisteredProjectType.CreateRegisteredProjectType(projectFactoryGuid);
			Debug.Assert(registeredProjectType != null, "Could not read the registry setting associated to this project.");
			if(registeredProjectType == null)
			{
				throw new InvalidOperationException();
			}
			return registeredProjectType;
		}
		public NestedProjectNode(ProjectNode root, ProjectElement element)
			: base(root, element)
		{
			this.IsExpanded = true;
		}
Ejemplo n.º 21
0
		/// <summary>
		/// Create dependent file node based on an msbuild item
		/// </summary>
		/// <param name="item">msbuild item</param>
		/// <returns>dependent file node</returns>
		public virtual DependentFileNode CreateDependentFileNode(ProjectElement item)
		{
			return new DependentFileNode(this, item);
		}
		/// <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;
			}

			foreach(MSBuild.BuildItem item in this.BuildProject.EvaluatedItems)
			{
				if(String.Compare(item.Name, 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;
		}
Ejemplo n.º 23
0
		/// <summary>
		/// To support virtual folders, override this method to return your own folder nodes
		/// </summary>
		/// <param name="path">Path to store for this folder</param>
		/// <param name="element">Element corresponding to the folder</param>
		/// <returns>A FolderNode that can then be added to the hierarchy</returns>
		protected internal virtual FolderNode CreateFolderNode(string path, ProjectElement element)
		{
			FolderNode folderNode = new FolderNode(this, path, element);
			return folderNode;
		}
		/// <summary>
		/// Adds references to this container from a MSBuild project.
		/// </summary>
		public void LoadReferencesFromBuildProject(MSBuild.Project buildProject)
		{
			foreach(string referenceType in SupportedReferenceTypes)
			{
				MSBuild.BuildItemGroup refererncesGroup = buildProject.GetEvaluatedItemsByName(referenceType);

				bool isAssemblyReference = referenceType == ProjectFileConstants.Reference;
				// If the project was loaded for browsing we should still create the nodes but as not resolved.
				if(this.ProjectMgr.HasPassedSecurityChecks && isAssemblyReference && this.ProjectMgr.Build(MsBuildTarget.ResolveAssemblyReferences) != MSBuildResult.Successful)
				{
					continue;
				}

				foreach(MSBuild.BuildItem item in refererncesGroup)
				{
					ProjectElement element = new ProjectElement(this.ProjectMgr, item, false);

					ReferenceNode node = CreateReferenceNode(referenceType, element);

					if(node != null)
					{
						// Make sure that we do not want to add the item twice to the ui hierarchy
						// We are using here the UI representation of the Node namely the Caption to find that out, in order to
						// avoid different representation problems.
						// Example :<Reference Include="EnvDTE80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
						//		  <Reference Include="EnvDTE80" />
						bool found = false;
						for(HierarchyNode n = this.FirstChild; n != null && !found; n = n.NextSibling)
						{
							if(String.Compare(n.Caption, node.Caption, StringComparison.OrdinalIgnoreCase) == 0)
							{
								found = true;
							}
						}

						if(!found)
						{
							this.AddChild(node);
						}
					}
				}
			}
		}