/// <summary>
		/// Creates a new project item from an existing item template file and adds it to the project. 
		/// </summary>
		/// <param name="fileName">The full path and file name of the template project file.</param>
		/// <param name="name">The file name to use for the new project item.</param>
		/// <returns>A ProjectItem object. </returns>
		public override EnvDTE.ProjectItem AddFromTemplate(string fileName, string name)
		{

			if(this.Project == null || this.Project.Project == null || this.Project.Project.Site == null || this.Project.Project.IsClosed)
			{
				throw new InvalidOperationException();
			}

			ProjectNode proj = this.Project.Project;
			EnvDTE.ProjectItem itemAdded = null;

			using(AutomationScope scope = new AutomationScope(this.Project.Project.Site))
			{
				// Determine the operation based on the extension of the filename.
				// We should run the wizard only if the extension is vstemplate
				// otherwise it's a clone operation
				VSADDITEMOPERATION op;

				if(Utilities.IsTemplateFile(fileName))
				{
					op = VSADDITEMOPERATION.VSADDITEMOP_RUNWIZARD;
				}
				else
				{
					op = VSADDITEMOPERATION.VSADDITEMOP_CLONEFILE;
				}

				VSADDRESULT[] result = new VSADDRESULT[1];

				// It is not a very good idea to throw since the AddItem might return Cancel or Abort.
				// The problem is that up in the call stack the wizard code does not check whether it has received a ProjectItem or not and will crash.
				// The other problem is that we cannot get add wizard dialog back if a cancel or abort was returned because we throw and that code will never be executed. Typical catch 22.
				ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, name, 0, new string[1] { fileName }, IntPtr.Zero, result));

				string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems);
				string templateFilePath = System.IO.Path.Combine(fileDirectory, name);
				itemAdded = this.EvaluateAddResult(result[0], templateFilePath);
			}

			return itemAdded;
		}
		/// <summary>
		/// Adds a folder to the collection of ProjectItems with the given name.
		/// 
		/// The kind must be null, empty string, or the string value of vsProjectItemKindPhysicalFolder.
		/// Virtual folders are not supported by this implementation.
		/// </summary>
		/// <param name="name">The name of the new folder to add</param>
		/// <param name="kind">A string representing a Guid of the folder kind.</param>
		/// <returns>A ProjectItem representing the newly added folder.</returns>
		public override ProjectItem AddFolder(string name, string kind)
		{
			if(this.Project == null || this.Project.Project == null || this.Project.Project.Site == null || this.Project.Project.IsClosed)
			{
				throw new InvalidOperationException();
			}
			//Verify name is not null or empty
			Utilities.ValidateFileName(this.Project.Project.Site, name);

			//Verify that kind is null, empty, or a physical folder
			if(!(string.IsNullOrEmpty(kind) || kind.Equals(EnvDTE.Constants.vsProjectItemKindPhysicalFolder)))
			{
				throw new ArgumentException("Parameter specification for AddFolder was not meet", "kind");
			}

			for(HierarchyNode child = this.NodeWithItems.FirstChild; child != null; child = child.NextSibling)
			{
				if(child.Caption.Equals(name, StringComparison.OrdinalIgnoreCase))
				{
					throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Folder already exists with the name '{0}'", name));
				}
			}

			ProjectNode proj = this.Project.Project;

			HierarchyNode newFolder = null;
			using(AutomationScope scope = new AutomationScope(this.Project.Project.Site))
			{

				//In the case that we are adding a folder to a folder, we need to build up
				//the path to the project node.
				name = Path.Combine(this.NodeWithItems.VirtualNodeName, name);

				newFolder = proj.CreateFolderNodes(name);
			}

			return newFolder.GetAutomationObject() as ProjectItem;
		}
		/// <summary>
		/// Adds an item to the project.
		/// </summary>
		/// <param name="path">The full path of the item to add.</param>
		/// <param name="op">The <paramref name="VSADDITEMOPERATION"/> to use when adding the item.</param>
		/// <returns>A ProjectItem object. </returns>
		protected virtual EnvDTE.ProjectItem AddItem(string path, VSADDITEMOPERATION op)
		{
			if(this.Project == null || this.Project.Project == null || this.Project.Project.Site == null || this.Project.Project.IsClosed)
			{
				throw new InvalidOperationException();
			}

			ProjectNode proj = this.Project.Project;

			EnvDTE.ProjectItem itemAdded = null;
			using(AutomationScope scope = new AutomationScope(this.Project.Project.Site))
			{
				VSADDRESULT[] result = new VSADDRESULT[1];
				ErrorHandler.ThrowOnFailure(proj.AddItem(this.NodeWithItems.ID, op, path, 0, new string[1] { path }, IntPtr.Zero, result));

				string fileName = System.IO.Path.GetFileName(path);
				string fileDirectory = proj.GetBaseDirectoryForAddingFiles(this.NodeWithItems);
				string filePathInProject = System.IO.Path.Combine(fileDirectory, fileName);

				itemAdded = this.EvaluateAddResult(result[0], filePathInProject);
			}

			return itemAdded;
		}
Ejemplo n.º 4
0
		/// <summary>
		/// Sets the value of the property at the specified index.
		/// </summary>
		/// <param name="index1">The index of the item to set.</param>
		/// <param name="index2">Reserved for future use.</param>
		/// <param name="index3">Reserved for future use.</param>
		/// <param name="index4">Reserved for future use.</param>
		/// <param name="value">The value to set.</param>
		public void set_IndexedValue(object index1, object index2, object index3, object index4, object value)
		{
			ParameterInfo[] par = pi.GetIndexParameters();
			int len = Math.Min(par.Length, 4);
			if(len == 0)
			{
				this.Value = value;
			}
			else
			{
				object[] index = new object[len];
				Array.Copy(new object[4] { index1, index2, index3, index4 }, index, len);

				using(AutomationScope scope = new AutomationScope(this.parent.Target.Node.ProjectMgr.Site))
				{
					this.pi.SetValue(this.parent.Target, value, index);
				}
			}

		}
Ejemplo n.º 5
0
		/// <summary>
		/// Saves or Save Asthe project.
		/// </summary>
		/// <param name="isCalledFromSaveAs">Flag determining which Save method called , the SaveAs or the Save.</param>
		/// <param name="fileName">The name of the project file.</param>        
		private void DoSave(bool isCalledFromSaveAs, string fileName)
		{
			if(fileName == null)
			{
				throw new ArgumentNullException("fileName");
			}

			if(this.project == null || this.project.Site == null || this.project.IsClosed)
			{
				throw new InvalidOperationException();
			}

			using(AutomationScope scope = new AutomationScope(this.project.Site))
			{
				// If an empty file name is passed in for Save then make the file name the project name.
				if(!isCalledFromSaveAs && string.IsNullOrEmpty(fileName))
				{
					// Use the solution service to save the project file. Note that we have to use the service
					// so that all the shell's elements are aware that we are inside a save operation and
					// all the file change listenters registered by the shell are suspended.

					// Get the cookie of the project file from the RTD.
					IVsRunningDocumentTable rdt = this.project.Site.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
					if(null == rdt)
					{
						throw new InvalidOperationException();
					}

					IVsHierarchy hier;
					uint itemid;
					IntPtr unkData;
					uint cookie;
					ErrorHandler.ThrowOnFailure(rdt.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, this.project.Url, out hier,
																		out itemid, out unkData, out cookie));
					if(IntPtr.Zero != unkData)
					{
						Marshal.Release(unkData);
					}

					// Verify that we have a cookie.
					if(0 == cookie)
					{
						// This should never happen because if the project is open, then it must be in the RDT.
						throw new InvalidOperationException();
					}

					// Get the IVsHierarchy for the project.
					IVsHierarchy prjHierarchy = HierarchyNode.GetOuterHierarchy(this.project);

					// Now get the soulution.
					IVsSolution solution = this.project.Site.GetService(typeof(SVsSolution)) as IVsSolution;
					// Verify that we have both solution and hierarchy.
					if((null == prjHierarchy) || (null == solution))
					{
						throw new InvalidOperationException();
					}

					ErrorHandler.ThrowOnFailure(solution.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_SaveIfDirty, prjHierarchy, cookie));
				}
				else
				{

					// We need to make some checks before we can call the save method on the project node.
					// This is mainly because it is now us and not the caller like in  case of SaveAs or Save that should validate the file name.
					// The IPersistFileFormat.Save method only does a validation that is necesseray to be performed. Example: in case of Save As the  
					// file name itself is not validated only the whole path. (thus a file name like file\file is accepted, since as a path is valid)

					// 1. The file name has to be valid. 
					string fullPath = fileName;
					try
					{
						if(!Path.IsPathRooted(fileName))
						{
							fullPath = Path.Combine(this.project.ProjectFolder, fileName);
						}
					}
					// We want to be consistent in the error message and exception we throw. fileName could be for example #¤&%"¤&"%  and that would trigger an ArgumentException on Path.IsRooted.
					catch(ArgumentException)
					{
						throw new InvalidOperationException(SR.GetString(SR.ErrorInvalidFileName, CultureInfo.CurrentUICulture));
					}

					// It might be redundant but we validate the file and the full path of the file being valid. The SaveAs would also validate the path.
					// If we decide that this is performance critical then this should be refactored.
					Utilities.ValidateFileName(this.project.Site, fullPath);

					if(!isCalledFromSaveAs)
					{
						// 2. The file name has to be the same 
						if(!NativeMethods.IsSamePath(fullPath, this.project.Url))
						{
							throw new InvalidOperationException();
						}

						ErrorHandler.ThrowOnFailure(this.project.Save(fullPath, 1, 0));
					}
					else
					{
						ErrorHandler.ThrowOnFailure(this.project.Save(fullPath, 0, 0));
					}
				}
			}

		}
Ejemplo n.º 6
0
		/// <summary>
		/// Removes the project from the current solution. 
		/// </summary>
		public virtual void Delete()
		{
			if(this.project == null || this.project.Site == null || this.project.IsClosed)
			{
				throw new InvalidOperationException();
			}

			using(AutomationScope scope = new AutomationScope(this.project.Site))
			{
				this.project.Remove(false);
			}
		}