/source2/VSIP/MPF/10.0/Src/CSharp/ProjectNode.cs
C# | 6517 lines | 5727 code | 314 blank | 476 comment | 221 complexity | 39e8ced0a98a2f0a74571103d48de716 MD5 | raw file
Possible License(s): BSD-2-Clause
Large files files are truncated, but you can click here to view the full file
- /***************************************************************************
-
- Copyright (c) Microsoft Corporation. All rights reserved.
- This code is licensed under the Visual Studio SDK license terms.
- THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
- ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
- IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
- PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
-
- ***************************************************************************/
-
- using System;
- using System.CodeDom.Compiler;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.Diagnostics;
- using System.Diagnostics.CodeAnalysis;
- using System.Globalization;
- using System.IO;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Text;
- using System.Xml;
- using EnvDTE;
- using Microsoft.Build.BackEnd;
- using Microsoft.Build.Evaluation;
- using Microsoft.Build.Execution;
- using Microsoft.VisualStudio.OLE.Interop;
- using Microsoft.VisualStudio.Shell;
- using Microsoft.VisualStudio.Shell.Interop;
- using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
- using IServiceProvider = System.IServiceProvider;
- using MSBuild = Microsoft.Build.Evaluation;
- using MSBuildConstruction = Microsoft.Build.Construction;
- using MSBuildExecution = Microsoft.Build.Execution;
- using OleConstants = Microsoft.VisualStudio.OLE.Interop.Constants;
- using VsCommands = Microsoft.VisualStudio.VSConstants.VSStd97CmdID;
- using VsCommands2K = Microsoft.VisualStudio.VSConstants.VSStd2KCmdID;
-
- namespace Microsoft.VisualStudio.Project
- {
- /// <summary>
- /// Manages the persistent state of the project (References, options, files, etc.) and deals with user interaction via a GUI in the form a hierarchy.
- /// </summary>
- [CLSCompliant(false)]
- [ComVisible(true)]
- public abstract partial class ProjectNode : HierarchyNode,
- IVsGetCfgProvider,
- IVsProject3,
- IVsAggregatableProject,
- IVsProjectFlavorCfgProvider,
- IPersistFileFormat,
- IVsProjectBuildSystem,
- IVsBuildPropertyStorage,
- IVsComponentUser,
- IVsDependencyProvider,
- IVsSccProject2,
- IBuildDependencyUpdate,
- IProjectEventsListener,
- IProjectEventsProvider,
- IReferenceContainerProvider,
- IVsProjectSpecialFiles,
- IVsProjectUpgrade,
- IVsDesignTimeAssemblyResolution,
- IVsSetTargetFrameworkWorkerCallback
- {
- #region nested types
-
- public enum ImageName
- {
- OfflineWebApp = 0,
- WebReferencesFolder = 1,
- OpenReferenceFolder = 2,
- ReferenceFolder = 3,
- Reference = 4,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SDL")]
- SDLWebReference = 5,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DISCO")]
- DISCOWebReference = 6,
- Folder = 7,
- OpenFolder = 8,
- ExcludedFolder = 9,
- OpenExcludedFolder = 10,
- ExcludedFile = 11,
- DependentFile = 12,
- MissingFile = 13,
- WindowsForm = 14,
- WindowsUserControl = 15,
- WindowsComponent = 16,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "XML")]
- XMLSchema = 17,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "XML")]
- XMLFile = 18,
- WebForm = 19,
- WebService = 20,
- WebUserControl = 21,
- WebCustomUserControl = 22,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ASP")]
- ASPPage = 23,
- GlobalApplicationClass = 24,
- WebConfig = 25,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "HTML")]
- HTMLPage = 26,
- StyleSheet = 27,
- ScriptFile = 28,
- TextFile = 29,
- SettingsFile = 30,
- Resources = 31,
- Bitmap = 32,
- Icon = 33,
- Image = 34,
- ImageMap = 35,
- XWorld = 36,
- Audio = 37,
- Video = 38,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "CAB")]
- CAB = 39,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "JAR")]
- JAR = 40,
- DataEnvironment = 41,
- PreviewFile = 42,
- DanglingReference = 43,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "XSLT")]
- XSLTFile = 44,
- Cursor = 45,
- AppDesignerFolder = 46,
- Data = 47,
- Application = 48,
- DataSet = 49,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "PFX")]
- PFX = 50,
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SNK")]
- SNK = 51,
-
- ImageLast = 51
- }
-
- /// <summary>
- /// Flags for specifying which events to stop triggering.
- /// </summary>
- [Flags]
- internal enum EventTriggering
- {
- TriggerAll = 0,
- DoNotTriggerHierarchyEvents = 1,
- DoNotTriggerTrackerEvents = 2
- }
-
- #endregion
-
- #region constants
- /// <summary>
- /// The user file extension.
- /// </summary>
- internal const string PerUserFileExtension = ".user";
-
- private Guid GUID_MruPage = new Guid("{19B97F03-9594-4c1c-BE28-25FF030113B3}");
-
- /// <summary>
- /// The VS command that allows projects to open Windows Explorer to the project directory.
- /// </summary>
- private const VsCommands2K ExploreFolderInWindowsCommand = (VsCommands2K)1635;
-
- #endregion
-
- #region fields
-
- private static readonly FrameworkName DefaultTargetFrameworkMoniker = new FrameworkName(".NETFramework", new Version(4, 0));
-
- private static Guid addComponentLastActiveTab = VSConstants.GUID_SolutionPage;
-
- private static uint addComponentDialogSizeX = 0;
-
- private static uint addComponentDialogSizeY = 0;
-
- /// <summary>
- /// List of output groups names and their associated target
- /// </summary>
- private static KeyValuePair<string, string>[] outputGroupNames =
- { // Name Target (MSBuild)
- new KeyValuePair<string, string>("Built", "BuiltProjectOutputGroup"),
- new KeyValuePair<string, string>("ContentFiles", "ContentFilesProjectOutputGroup"),
- new KeyValuePair<string, string>("LocalizedResourceDlls", "SatelliteDllsProjectOutputGroup"),
- new KeyValuePair<string, string>("Documentation", "DocumentationProjectOutputGroup"),
- new KeyValuePair<string, string>("Symbols", "DebugSymbolsProjectOutputGroup"),
- new KeyValuePair<string, string>("SourceFiles", "SourceFilesProjectOutputGroup"),
- new KeyValuePair<string, string>("XmlSerializer", "SGenFilesOutputGroup"),
- };
-
- /// <summary>A project will only try to build if it can obtain a lock on this object</summary>
- private volatile static object BuildLock = new object();
-
- /// <summary>Maps integer ids to project item instances</summary>
- private EventSinkCollection itemIdMap = new EventSinkCollection();
-
- /// <summary>A service provider call back object provided by the IDE hosting the project manager</summary>
- private ServiceProvider site;
-
- public static ServiceProvider ServiceProvider { get; set; }
-
- private TrackDocumentsHelper tracker;
-
- /// <summary>
- /// A cached copy of project options.
- /// </summary>
- private ProjectOptions options;
-
- /// <summary>
- /// This property returns the time of the last change made to this project.
- /// It is not the time of the last change on the project file, but actually of
- /// the in memory project settings. In other words, it is the last time that
- /// SetProjectDirty was called.
- /// </summary>
- private DateTime lastModifiedTime;
-
- /// <summary>
- /// MSBuild engine we are going to use
- /// </summary>
- private MSBuild.ProjectCollection buildEngine;
-
- private Microsoft.Build.Utilities.Logger buildLogger;
-
- private bool useProvidedLogger;
-
- private MSBuild.Project buildProject;
-
- private MSBuildExecution.ProjectInstance currentConfig;
-
- private DesignTimeAssemblyResolution designTimeAssemblyResolution;
-
- private ConfigProvider configProvider;
-
- private TaskProvider taskProvider;
-
- private string filename;
-
- private Microsoft.VisualStudio.Shell.Url baseUri;
-
- private bool isDirty;
-
- private bool isNewProject;
-
- private bool projectOpened;
-
- private bool buildIsPrepared;
-
- private ImageHandler imageHandler;
-
- private string errorString;
-
- private string warningString;
-
- private Guid projectIdGuid;
-
- private bool isClosed;
-
- private EventTriggering eventTriggeringFlag = EventTriggering.TriggerAll;
-
- private bool invokeMSBuildWhenResumed;
-
- private uint suspendMSBuildCounter;
-
- private bool canFileNodesHaveChilds;
-
- private bool isProjectEventsListener = true;
-
- /// <summary>
- /// The build dependency list passed to IVsDependencyProvider::EnumDependencies
- /// </summary>
- private List<IVsBuildDependency> buildDependencyList = new List<IVsBuildDependency>();
-
- /// <summary>
- /// Defines if Project System supports Project Designer
- /// </summary>
- private bool supportsProjectDesigner;
-
- private bool showProjectInSolutionPage = true;
-
- private bool buildInProcess;
-
- /// <summary>
- /// Field for determining whether sourcecontrol should be disabled.
- /// </summary>
- private bool disableScc;
-
- private string sccProjectName;
-
- private string sccLocalPath;
-
- private string sccAuxPath;
-
- private string sccProvider;
-
- /// <summary>
- /// Flag for controling how many times we register with the Scc manager.
- /// </summary>
- private bool isRegisteredWithScc;
-
- /// <summary>
- /// Flag for controling query edit should communicate with the scc manager.
- /// </summary>
- private bool disableQueryEdit;
-
- /// <summary>
- /// Control if command with potential destructive behavior such as delete should
- /// be enabled for nodes of this project.
- /// </summary>
- private bool canProjectDeleteItems;
-
- /// <summary>
- /// Token processor used by the project sample.
- /// </summary>
- private TokenProcessor tokenProcessor;
-
- /// <summary>
- /// Member to store output base relative path. Used by OutputBaseRelativePath property
- /// </summary>
- private string outputBaseRelativePath = "bin";
-
- private IProjectEvents projectEventsProvider;
-
- /// <summary>
- /// Used for flavoring to hold the XML fragments
- /// </summary>
- private XmlDocument xmlFragments;
-
- /// <summary>
- /// Used to map types to CATID. This provide a generic way for us to do this
- /// and make it simpler for a project to provide it's CATIDs for the different type of objects
- /// for which it wants to support extensibility. This also enables us to have multiple
- /// type mapping to the same CATID if we choose to.
- /// </summary>
- private Dictionary<Type, Guid> catidMapping = new Dictionary<Type, Guid>();
-
- /// <summary>
- /// The internal package implementation.
- /// </summary>
- private ProjectPackage package;
-
- // Has the object been disposed.
- private bool isDisposed;
- #endregion
-
- #region abstract properties
- /// <summary>
- /// This Guid must match the Guid you registered under
- /// HKLM\Software\Microsoft\VisualStudio\%version%\Projects.
- /// Among other things, the Project framework uses this
- /// guid to find your project and item templates.
- /// </summary>
- public abstract Guid ProjectGuid
- {
- get;
- }
-
- /// <summary>
- /// Returns a caption for VSHPROPID_TypeName.
- /// </summary>
- /// <returns></returns>
- public abstract string ProjectType
- {
- get;
- }
- #endregion
-
- #region virtual properties
- /// <summary>
- /// This is the project instance guid that is peristed in the project file
- /// </summary>
- [System.ComponentModel.BrowsableAttribute(false)]
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID")]
- public virtual Guid ProjectIDGuid
- {
- get
- {
- return this.projectIdGuid;
- }
- set
- {
- if (this.projectIdGuid != value)
- {
- this.projectIdGuid = value;
- if (this.buildProject != null)
- {
- this.SetProjectProperty("ProjectGuid", this.projectIdGuid.ToString("B"));
- }
- }
- }
- }
- #endregion
-
- #region properties
-
- #region overridden properties
- public override int MenuCommandId
- {
- get
- {
- return VsMenus.IDM_VS_CTXT_PROJNODE;
- }
- }
-
- public override string Url
- {
- get
- {
- return this.GetMkDocument();
- }
- }
-
- public override string Caption
- {
- get
- {
- // Default to file name
- string caption = this.buildProject.FullPath;
- if (String.IsNullOrEmpty(caption))
- {
- if (this.buildProject.GetProperty(ProjectFileConstants.Name) != null)
- {
- caption = this.buildProject.GetProperty(ProjectFileConstants.Name).EvaluatedValue;
- if (caption == null || caption.Length == 0)
- {
- caption = this.ItemNode.GetMetadata(ProjectFileConstants.Include);
- }
- }
- }
- else
- {
- caption = Path.GetFileNameWithoutExtension(caption);
- }
-
- return caption;
- }
- }
-
- public override Guid ItemTypeGuid
- {
- get
- {
- return this.ProjectGuid;
- }
- }
-
- public override int ImageIndex
- {
- get
- {
- return (int)ProjectNode.ImageName.Application;
- }
- }
-
-
- #endregion
-
- #region virtual properties
-
- public virtual string ErrorString
- {
- get
- {
- if (this.errorString == null)
- {
- this.errorString = SR.GetString(SR.Error, CultureInfo.CurrentUICulture);
- }
-
- return this.errorString;
- }
- }
-
- public virtual string WarningString
- {
- get
- {
- if (this.warningString == null)
- {
- this.warningString = SR.GetString(SR.Warning, CultureInfo.CurrentUICulture);
- }
-
- return this.warningString;
- }
- }
-
- /// <summary>
- /// The target name that will be used for evaluating the project file (i.e., pseudo-builds).
- /// This target is used to trigger a build with when the project system changes.
- /// Example: The language projrcts are triggering a build with the Compile target whenever
- /// the project system changes.
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "ReEvaluate")]
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Re")]
- protected internal virtual string ReEvaluateProjectFileTargetName
- {
- get
- {
- return null;
- }
- }
-
- /// <summary>
- /// This is the object that will be returned by EnvDTE.Project.Object for this project
- /// </summary>
- protected internal virtual object ProjectObject
- {
- get
- {
- return null;
- }
- }
-
- /// <summary>
- /// Override this property to specify when the project file is dirty.
- /// </summary>
- protected virtual bool IsProjectFileDirty
- {
- get
- {
- string document = this.GetMkDocument();
-
- if (String.IsNullOrEmpty(document))
- {
- return this.isDirty;
- }
-
- return (this.isDirty || !File.Exists(document));
- }
- }
-
- /// <summary>
- /// True if the project uses the Project Designer Editor instead of the property page frame to edit project properties.
- /// </summary>
- protected virtual bool SupportsProjectDesigner
- {
- get
- {
- return this.supportsProjectDesigner;
- }
- set
- {
- this.supportsProjectDesigner = value;
- }
-
- }
-
- protected virtual Guid ProjectDesignerEditor
- {
- get
- {
- return VSConstants.GUID_ProjectDesignerEditor;
- }
- }
-
- /// <summary>
- /// Defines the flag that supports the VSHPROPID.ShowProjInSolutionPage
- /// </summary>
- protected virtual bool ShowProjectInSolutionPage
- {
- get
- {
- return this.showProjectInSolutionPage;
- }
- set
- {
- this.showProjectInSolutionPage = value;
- }
- }
-
- #endregion
-
- /// <summary>
- /// Gets or sets the ability of a project filenode to have child nodes (sub items).
- /// Example would be C#/VB forms having resx and designer files.
- /// </summary>
- protected internal bool CanFileNodesHaveChilds
- {
- get
- {
- return canFileNodesHaveChilds;
- }
- set
- {
- canFileNodesHaveChilds = value;
- }
- }
-
- /// <summary>
- /// Get and set the Token processor.
- /// </summary>
- public TokenProcessor FileTemplateProcessor
- {
- get
- {
- if (tokenProcessor == null)
- tokenProcessor = new TokenProcessor();
- return tokenProcessor;
- }
- set
- {
- tokenProcessor = value;
- }
- }
-
- /// <summary>
- /// Gets a service provider object provided by the IDE hosting the project
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")]
- public IServiceProvider Site
- {
- get
- {
- return this.site;
- }
- }
-
- /// <summary>
- /// Gets an ImageHandler for the project node.
- /// </summary>
- public ImageHandler ImageHandler
- {
- get
- {
- if (null == imageHandler)
- {
- imageHandler = new ImageHandler(typeof(ProjectNode).Assembly.GetManifestResourceStream("Microsoft.VisualStudio.Project.Resources.imagelis.bmp"));
- }
- return imageHandler;
- }
- }
-
- /// <summary>
- /// This property returns the time of the last change made to this project.
- /// It is not the time of the last change on the project file, but actually of
- /// the in memory project settings. In other words, it is the last time that
- /// SetProjectDirty was called.
- /// </summary>
- public DateTime LastModifiedTime
- {
- get
- {
- return this.lastModifiedTime;
- }
- }
-
- /// <summary>
- /// Determines whether this project is a new project.
- /// </summary>
- public bool IsNewProject
- {
- get
- {
- return this.isNewProject;
- }
- }
-
- /// <summary>
- /// Gets the path to the folder containing the project.
- /// </summary>
- public string ProjectFolder
- {
- get
- {
- return Path.GetDirectoryName(this.filename);
- }
- }
-
- /// <summary>
- /// Gets or sets the project filename.
- /// </summary>
- public string ProjectFile
- {
- get
- {
- return Path.GetFileName(this.filename);
- }
- set
- {
- this.SetEditLabel(value);
- }
- }
-
- /// <summary>
- /// Gets the Base Uniform Resource Identifier (URI).
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "URI")]
- public Microsoft.VisualStudio.Shell.Url BaseURI
- {
- get
- {
- if (baseUri == null && this.buildProject != null)
- {
- string path = System.IO.Path.GetDirectoryName(this.buildProject.FullPath);
- // Uri/Url behave differently when you have trailing slash and when you dont
- if (!path.EndsWith("\\", StringComparison.Ordinal) && !path.EndsWith("/", StringComparison.Ordinal))
- path += "\\";
- baseUri = new Url(path);
- }
-
- Debug.Assert(baseUri != null, "Base URL should not be null. Did you call BaseURI before loading the project?");
- return baseUri;
- }
- }
-
- /// <summary>
- /// Gets whether or not the project is closed.
- /// </summary>
- public bool IsClosed
- {
- get
- {
- return this.isClosed;
- }
- }
-
- /// <summary>
- /// Gets whether or not the project is being built.
- /// </summary>
- public bool BuildInProgress
- {
- get
- {
- return buildInProcess;
- }
- }
-
- /// <summary>
- /// Gets or set the relative path to the folder containing the project ouput.
- /// </summary>
- public virtual string OutputBaseRelativePath
- {
- get
- {
- return this.outputBaseRelativePath;
- }
- set
- {
- if (Path.IsPathRooted(value))
- {
- throw new ArgumentException("Path must not be rooted.");
- }
-
- this.outputBaseRelativePath = value;
- }
- }
-
- public FrameworkName TargetFrameworkMoniker
- {
- get
- {
- if (this.options == null)
- {
- GetProjectOptions();
- }
- if (this.options != null)
- {
- return this.options.TargetFrameworkMoniker ?? DefaultTargetFrameworkMoniker;
- }
- else
- {
- return DefaultTargetFrameworkMoniker;
- }
- }
-
- set
- {
- if (this.options == null)
- {
- GetProjectOptions();
- }
-
- if (value == null)
- {
- value = DefaultTargetFrameworkMoniker;
- }
-
- if (this.options.TargetFrameworkMoniker != value)
- {
- this.OnTargetFrameworkMonikerChanged(this.options, this.options.TargetFrameworkMoniker, value);
- }
- }
- }
-
- /// <summary>
- /// Gets or sets the flag whether query edit should communicate with the scc manager.
- /// </summary>
- protected bool DisableQueryEdit
- {
- get
- {
- return this.disableQueryEdit;
- }
- set
- {
- this.disableQueryEdit = value;
- }
- }
-
- /// <summary>
- /// Gets a collection of integer ids that maps to project item instances
- /// </summary>
- internal EventSinkCollection ItemIdMap
- {
- get
- {
- return this.itemIdMap;
- }
- }
-
- /// <summary>
- /// Get the helper object that track document changes.
- /// </summary>
- internal TrackDocumentsHelper Tracker
- {
- get
- {
- return this.tracker;
- }
- }
-
- /// <summary>
- /// Gets or sets the build logger.
- /// </summary>
- protected Microsoft.Build.Utilities.Logger BuildLogger
- {
- get
- {
- return this.buildLogger;
- }
- set
- {
- this.buildLogger = value;
- this.useProvidedLogger = true;
- }
- }
-
- /// <summary>
- /// Gets the taskprovider.
- /// </summary>
- protected TaskProvider TaskProvider
- {
- get
- {
- return this.taskProvider;
- }
- }
-
- /// <summary>
- /// Gets the project file name.
- /// </summary>
- protected string FileName
- {
- get
- {
- return this.filename;
- }
- }
-
- protected bool IsIdeInCommandLineMode
- {
- get
- {
- bool cmdline = false;
- var shell = this.site.GetService(typeof(SVsShell)) as IVsShell;
- if (shell != null)
- {
- object obj;
- Marshal.ThrowExceptionForHR(shell.GetProperty((int)__VSSPROPID.VSSPROPID_IsInCommandLineMode, out obj));
- cmdline = (bool)obj;
- }
- return cmdline;
- }
- }
-
- /// <summary>
- /// Gets the configuration provider.
- /// </summary>
- protected ConfigProvider ConfigProvider
- {
- get
- {
- if (this.configProvider == null)
- {
- this.configProvider = CreateConfigProvider();
- }
-
- return this.configProvider;
- }
- }
-
- /// <summary>
- /// Gets or sets whether or not source code control is disabled for this project.
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Scc")]
- protected bool IsSccDisabled
- {
- get
- {
- return this.disableScc;
- }
- set
- {
- this.disableScc = value;
- }
- }
-
- /// <summary>
- /// Gets or set whether items can be deleted for this project.
- /// Enabling this feature can have the potential destructive behavior such as deleting files from disk.
- /// </summary>
- protected internal bool CanProjectDeleteItems
- {
- get
- {
- return canProjectDeleteItems;
- }
- set
- {
- canProjectDeleteItems = value;
- }
- }
-
- /// <summary>
- /// Determines whether the project was fully opened. This is set when the OnAfterOpenProject has triggered.
- /// </summary>
- protected internal bool HasProjectOpened
- {
- get
- {
- return this.projectOpened;
- }
- }
-
- /// <summary>
- /// Gets or sets event triggering flags.
- /// </summary>
- internal EventTriggering EventTriggeringFlag
- {
- get
- {
- return this.eventTriggeringFlag;
- }
- set
- {
- this.eventTriggeringFlag = value;
- }
- }
-
- /// <summary>
- /// Defines the build project that has loaded the project file.
- /// </summary>
- protected internal MSBuild.Project BuildProject
- {
- get
- {
- return this.buildProject;
- }
- set
- {
- SetBuildProject(value);
- }
- }
-
- /// <summary>
- /// Gets the current config.
- /// </summary>
- /// <value>The current config.</value>
- protected internal Microsoft.Build.Execution.ProjectInstance CurrentConfig
- {
- get { return this.currentConfig; }
- }
-
- /// <summary>
- /// Defines the build engine that is used to build the project file.
- /// </summary>
- internal MSBuild.ProjectCollection BuildEngine
- {
- get
- {
- return this.buildEngine;
- }
- set
- {
- this.buildEngine = value;
- }
- }
-
- /// <summary>
- /// The internal package implementation.
- /// </summary>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal ProjectPackage Package
- {
- get
- {
- return this.package;
- }
- set
- {
- this.package = value;
- }
- }
- #endregion
-
- #region ctor
-
- protected ProjectNode()
- {
- this.Initialize();
- }
- #endregion
-
- #region overridden methods
- protected override NodeProperties CreatePropertiesObject()
- {
- return new ProjectNodeProperties(this);
- }
-
- /// <summary>
- /// Sets the properties for the project node.
- /// </summary>
- /// <param name="propid">Identifier of the hierarchy property. For a list of propid values, <see cref="__VSHPROPID"/> </param>
- /// <param name="value">The value to set. </param>
- /// <returns>A success or failure value.</returns>
- public override int SetProperty(int propid, object value)
- {
- __VSHPROPID id = (__VSHPROPID)propid;
-
- switch (id)
- {
- case __VSHPROPID.VSHPROPID_ShowProjInSolutionPage:
- this.ShowProjectInSolutionPage = (bool)value;
- return VSConstants.S_OK;
- }
-
- return base.SetProperty(propid, value);
- }
-
- /// <summary>
- /// Renames the project node.
- /// </summary>
- /// <param name="label">The new name</param>
- /// <returns>A success or failure value.</returns>
- public override int SetEditLabel(string label)
- {
- // Validate the filename.
- if (String.IsNullOrEmpty(label))
- {
- throw new InvalidOperationException(SR.GetString(SR.ErrorInvalidFileName, CultureInfo.CurrentUICulture));
- }
- else if (this.ProjectFolder.Length + label.Length + 1 > NativeMethods.MAX_PATH)
- {
- throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.PathTooLong, CultureInfo.CurrentUICulture), label));
- }
- else if (Utilities.IsFileNameInvalid(label))
- {
- throw new InvalidOperationException(SR.GetString(SR.ErrorInvalidFileName, CultureInfo.CurrentUICulture));
- }
-
- string fileName = Path.GetFileNameWithoutExtension(label);
-
- // if there is no filename or it starts with a leading dot issue an error message and quit.
- if (String.IsNullOrEmpty(fileName) || fileName[0] == '.')
- {
- throw new InvalidOperationException(SR.GetString(SR.FileNameCannotContainALeadingPeriod, CultureInfo.CurrentUICulture));
- }
-
- // Nothing to do if the name is the same
- string oldFileName = Path.GetFileNameWithoutExtension(this.Url);
- if (String.Compare(oldFileName, label, StringComparison.Ordinal) == 0)
- {
- return VSConstants.S_FALSE;
- }
-
- // Now check whether the original file is still there. It could have been renamed.
- if (!File.Exists(this.Url))
- {
- throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FileOrFolderCannotBeFound, CultureInfo.CurrentUICulture), this.ProjectFile));
- }
-
- // Get the full file name and then rename the project file.
- string newFile = Path.Combine(this.ProjectFolder, label);
- string extension = Path.GetExtension(this.Url);
-
- // Make sure it has the correct extension
- if (String.Compare(Path.GetExtension(newFile), extension, StringComparison.OrdinalIgnoreCase) != 0)
- {
- newFile += extension;
- }
-
- this.RenameProjectFile(newFile);
- return VSConstants.S_OK;
- }
-
- /// <summary>
- /// Gets the automation object for the project node.
- /// </summary>
- /// <returns>An instance of an EnvDTE.Project implementation object representing the automation object for the project.</returns>
- public override object GetAutomationObject()
- {
- return new Automation.OAProject(this);
- }
-
- /// <summary>
- /// Closes the project node.
- /// </summary>
- /// <returns>A success or failure value.</returns>
- public override int Close()
- {
- int hr = VSConstants.S_OK;
- try
- {
- // Walk the tree and close all nodes.
- // This has to be done before the project closes, since we want still state available for the ProjectMgr on the nodes
- // when nodes are closing.
- try
- {
- CloseAllNodes(this);
- }
- finally
- {
- this.Dispose(true);
- }
- }
- catch (COMException e)
- {
- hr = e.ErrorCode;
- }
- finally
- {
- ErrorHandler.ThrowOnFailure(base.Close());
- }
-
- this.isClosed = true;
-
- return hr;
- }
-
- /// <summary>
- /// Sets the service provider from which to access the services.
- /// </summary>
- /// <param name="site">An instance to an Microsoft.VisualStudio.OLE.Interop object</param>
- /// <returns>A success or failure value.</returns>
- public override int SetSite(Microsoft.VisualStudio.OLE.Interop.IServiceProvider site)
- {
- CCITracing.TraceCall();
- this.site = new ServiceProvider(site);
- ServiceProvider = this.site;
-
- if (taskProvider != null)
- {
- taskProvider.Dispose();
- }
- taskProvider = new TaskProvider(this.site);
-
- return VSConstants.S_OK;
- }
-
- /// <summary>
- /// Gets the properties of the project node.
- /// </summary>
- /// <param name="propId">The __VSHPROPID of the property.</param>
- /// <returns>A property dependent value. See: <see cref="__VSHPROPID"/> for details.</returns>
- public override object GetProperty(int propId)
- {
- switch ((__VSHPROPID)propId)
- {
- case __VSHPROPID.VSHPROPID_ConfigurationProvider:
- return this.ConfigProvider;
-
- case __VSHPROPID.VSHPROPID_ProjectName:
- return this.Caption;
-
- case __VSHPROPID.VSHPROPID_ProjectDir:
- return this.ProjectFolder;
-
- case __VSHPROPID.VSHPROPID_TypeName:
- return this.ProjectType;
-
- case __VSHPROPID.VSHPROPID_ShowProjInSolutionPage:
- return this.ShowProjectInSolutionPage;
-
- case __VSHPROPID.VSHPROPID_ExpandByDefault:
- return true;
-
- // Use the same icon as if the folder was closed
- case __VSHPROPID.VSHPROPID_OpenFolderIconIndex:
- return GetProperty((int)__VSHPROPID.VSHPROPID_IconIndex);
- }
-
- switch ((__VSHPROPID2)propId)
- {
- case __VSHPROPID2.VSHPROPID_SupportsProjectDesigner:
- return this.SupportsProjectDesigner;
-
- case __VSHPROPID2.VSHPROPID_PropertyPagesCLSIDList:
- return Utilities.CreateSemicolonDelimitedListOfStringFromGuids(this.GetConfigurationIndependentPropertyPages());
-
- case __VSHPROPID2.VSHPROPID_CfgPropertyPagesCLSIDList:
- return Utilities.CreateSemicolonDelimitedListOfStringFromGuids(this.GetConfigurationDependentPropertyPages());
-
- case __VSHPROPID2.VSHPROPID_PriorityPropertyPagesCLSIDList:
- return Utilities.CreateSemicolonDelimitedListOfStringFromGuids(this.GetPriorityProjectDesignerPages());
-
- case __VSHPROPID2.VSHPROPID_Container:
- return true;
- default:
- break;
- }
-
- return base.GetProperty(propId);
- }
-
- /// <summary>
- /// Gets the GUID value of the node.
- /// </summary>
- /// <param name="propid">A __VSHPROPID or __VSHPROPID2 value of the guid property</param>
- /// <param name="guid">The guid to return for the property.</param>
- /// <returns>A success or failure value.</returns>
- public override int GetGuidProperty(int propid, out Guid guid)
- {
- guid = Guid.Empty;
- if ((__VSHPROPID)propid == __VSHPROPID.VSHPROPID_ProjectIDGuid)
- {
- guid = this.ProjectIDGuid;
- }
- else if (propid == (int)__VSHPROPID.VSHPROPID_CmdUIGuid)
- {
- guid = this.ProjectGuid;
- }
- else if ((__VSHPROPID2)propid == __VSHPROPID2.VSHPROPID_ProjectDesignerEditor && this.SupportsProjectDesigner)
- {
- guid = this.ProjectDesignerEditor;
- }
- else
- {
- base.GetGuidProperty(propid, out guid);
- }
-
- if (guid.CompareTo(Guid.Empty) == 0)
- {
- return VSConstants.DISP_E_MEMBERNOTFOUND;
- }
-
- return VSConstants.S_OK;
- }
-
- /// <summary>
- /// Sets Guid properties for the project node.
- /// </summary>
- /// <param name="propid">A __VSHPROPID or __VSHPROPID2 value of the guid property</param>
- /// <param name="guid">The guid value to set.</param>
- /// <returns>A success or failure value.</returns>
- public override int SetGuidProperty(int propid, ref Guid guid)
- {
- switch ((__VSHPROPID)propid)
- {
- case __VSHPROPID.VSHPROPID_ProjectIDGuid:
- this.ProjectIDGuid = guid;
- return VSConstants.S_OK;
- }
- CCITracing.TraceCall(String.Format(CultureInfo.CurrentCulture, "Property {0} not found", propid));
- return VSConstants.DISP_E_MEMBERNOTFOUND;
- }
-
- /// <summary>
- /// Removes items from the hierarchy.
- /// </summary>
- /// <devdoc>Project overwrites this.</devdoc>
- public override void Remove(bool removeFromStorage)
- {
- // the project will not be deleted from disk, just removed
- if (removeFromStorage)
- {
- return;
- }
-
- // Remove the entire project from the solution
- IVsSolution solution = this.Site.GetService(typeof(SVsSolution)) as IVsSolution;
- uint iOption = 1; // SLNSAVEOPT_PromptSave
- ErrorHandler.ThrowOnFailure(solution.CloseSolutionElement(iOption, this, 0));
- }
-
- /// <summary>
- /// Gets the moniker for the project node. That is the full path of the project file.
- /// </summary>
- /// <returns>The moniker for the project file.</returns>
- public override string GetMkDocument()
- {
- Debug.Assert(!String.IsNullOrEmpty(this.filename));
- Debug.Assert(this.BaseURI != null && !String.IsNullOrEmpty(this.BaseURI.AbsoluteUrl));
- return Path.Combine(this.BaseURI.AbsoluteUrl, this.filename);
- }
-
- /// <summary>
- /// Disposes the project node object.
- /// </summary>
- /// <param name="disposing">Flag determining ehether it was deterministic or non deterministic clean up.</param>
- protected override void Dispose(bool disposing)
- {
- if (this.isDisposed)
- {
- return;
- }
-
- try
- {
- try
- {
- this.UnRegisterProject();
- }
- finally
- {
- try
- {
- this.RegisterClipboardNotifications(false);
- }
- finally
- {
- try
- {
- if (this.projectEventsProvider != null)
- {
- this.projectEventsProvider.AfterProjectFileOpened -= this.OnAfterProjectOpen;
- }
- if (this.taskProvider != null)
- {
- taskProvider.Tasks.Clear();
- this.taskProvider.Dispose();
- this.taskProvider = null;
- }
-
- if (this.buildLogger != null)
- {
- this.buildLogger.Shutdown();
- buildLogger = null;
- }
-
- if (this.site != null)
- {
- this.site.Dispose();
- }
- }
- finally
- {
- this.buildEngine = null;
- }
- }
- }
-
- if (this.buildProject != null)
- {
- this.buildProject.ProjectCollection.UnloadProject(this.buildProject);
- this.buildProject.ProjectCollection.UnloadProject(this.buildProject.Xml);
- this.buildProject = null;
- }
-
- if (null != imageHandler)
- {
- imageHandler.Close();
- imageHandler = null;
- }
- }
- finally
- {
- base.Dispose(disposing);
- this.isDisposed = true;
- }
- }
-
- /// <summary>
- /// Handles command status on the project node. If a command cannot be handled then the base should be called.
- /// </summary>
- /// <param name="cmdGroup">A unique identifier of the command group. The pguidCmdGroup parameter can be NULL to specify the standard group.</param>
- /// <param name="cmd">The command to query status for.</param>
- /// <param name="pCmdText">Pointer to an OLECMDTEXT structure in which to return the name and/or status information of a single command. Can be NULL to indicate that the caller does not require this information.</param>
- /// <param name="result">An out parameter specifying the QueryStatusResult of the command.</param>
- /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
- protected override int QueryStatusOnNode(Guid cmdGroup, uint cmd, IntPtr pCmdText, ref QueryStatusResult result)
- {
- if (cmdGroup == VsMenus.guidStandardCommandSet97)
- {
- switch ((VsCommands)cmd)
- {
- case VsCommands.Copy:
- case VsCommands.Paste:
- case VsCommands.Cut:
- case VsCommands.Rename:
- case VsCommands.Exit:
- case VsCommands.ProjectSettings:
- case VsCommands.BuildSln:
- case VsCommands.UnloadProject:
- result |= QueryStatusResult.SUPPORTED | QueryStatusResult.ENABLED;
- return VSConstants.S_OK;
-
- case VsCommands.ViewForm:
- if (this.HasDesigner)
- {
- result |= QueryStatusResult.SUPPORTED | QueryStatusResult.ENABLED;
- return VSConstants.S_OK;
- }
- break;
-
- case VsCommands.CancelBuild:
- result |= QueryStatusResult.SUPPORTED;
- if (this.buildInProcess)
- result |= QueryStatusResult.ENABLED;
- else
- result |= QueryStatusResult.INVISIBLE;
- return VSConstants.S_OK;
-
- case VsCommands.NewFolder:
- case VsCommands.AddNewItem:
- case VsCommands.AddExistingItem:
- result |= QueryStatusResult.SUPPORTED | QueryStatusResult.ENABLED;
- return VSConstants.S_OK;
-
- case VsCommands.SetStartupProject:
- result |= QueryStatusResult.SUPPORTED | QueryStatusResult.ENABLED;
- return VSConstants.S_OK;
- }
- }
- else if (cmdGroup == VsMenus.guidStandardCommandSet2K)
- {
-
- switch ((VsCommands2K)cmd)
- {
- case VsCommands2K.ADDREFERENCE:
- result |= QueryStatusResult.SUPPORTED | QueryStatusResult.ENABLED;
- return VSConstants.S_OK;
-
- case VsCommands2K.EXCLUDEFROMPROJECT:
- result |= QueryStatusResult.SUPPORTED | QueryStatusResult.INVISIBLE;
- return VSConstants.S_OK;
-
- case ExploreFolderInWindowsCommand:
- result |= QueryStatusResult.SUPPORTED | QueryStatusResult.ENABLED;
- return VSConstants.S_OK;
- }
- }
- else
- {
- return (int)OleConstants.OLECMDERR_E_UNKNOWNGROUP;
- }
-
- return base.QueryStatusOnNode(cmdGroup, cmd, pCmdText, ref result);
- }
-
- /// <summary>
- /// Handles command execution.
- /// </summary>
- /// <param name="cmdGroup">Unique identifier of the command group</param>
- /// <param name="cmd">The command to be executed.</param>
- /// <param name="nCmdexecopt">Values describe how the object should execute the command.</param>
- /// <param name="pvaIn">Pointer to a VARIANTARG structure containing input arguments. Can be NULL</param>
- /// <param name="pvaOut">VARIANTARG structure to receive command output. Can b…
Large files files are truncated, but you can click here to view the full file