/DevTools/MPF/ProjectNode.cs
C# | 6613 lines | 5798 code | 317 blank | 498 comment | 222 complexity | 59e07259d68891bbfa288652f7048cf8 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- // ProjectNode.cs
- //
- // Copyright (c) 2013 The GreenBox Development LLC, all rights reserved
- //
- // This file is a proprietary part of GreenBox3D, disclosing the content
- // of this file without the owner consent may lead to legal actions
- using System;
- using System.CodeDom.Compiler;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.ComponentModel;
- 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.Build.Framework;
- using Microsoft.Build.Utilities;
- using Microsoft.VisualStudio.OLE.Interop;
- using Microsoft.VisualStudio.Project.Automation;
- using Microsoft.VisualStudio.Shell;
- using Microsoft.VisualStudio.Shell.Interop;
- using Constants = EnvDTE.Constants;
- 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 Process = System.Diagnostics.Process;
- using ProjectItem = EnvDTE.ProjectItem;
- 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";
- /// <summary>
- /// The VS command that allows projects to open Windows Explorer to the project directory.
- /// </summary>
- private const VsCommands2K ExploreFolderInWindowsCommand = (VsCommands2K)1635;
- private readonly Guid GUID_MruPage = new Guid("{19B97F03-9594-4c1c-BE28-25FF030113B3}");
- #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 readonly 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 static volatile object BuildLock = new object();
- /// <summary>
- /// The build dependency list passed to IVsDependencyProvider::EnumDependencies
- /// </summary>
- private readonly List<IVsBuildDependency> buildDependencyList = new List<IVsBuildDependency>();
- /// <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 readonly Dictionary<Type, Guid> catidMapping = new Dictionary<Type, Guid>();
- /// <summary>Maps integer ids to project item instances</summary>
- private readonly EventSinkCollection itemIdMap = new EventSinkCollection();
- private Url baseUri;
- /// <summary>
- /// MSBuild engine we are going to use
- /// </summary>
- private ProjectCollection buildEngine;
- private bool buildInProcess;
- private bool buildIsPrepared;
- private Logger buildLogger;
- private MSBuild.Project buildProject;
- private bool canFileNodesHaveChilds;
- /// <summary>
- /// Control if command with potential destructive behavior such as delete should
- /// be enabled for nodes of this project.
- /// </summary>
- private bool canProjectDeleteItems;
- private ConfigProvider configProvider;
- private ProjectInstance currentConfig;
- private DesignTimeAssemblyResolution designTimeAssemblyResolution;
- /// <summary>
- /// Flag for controling query edit should communicate with the scc manager.
- /// </summary>
- private bool disableQueryEdit;
- /// <summary>
- /// Field for determining whether sourcecontrol should be disabled.
- /// </summary>
- private bool disableScc;
- private string errorString;
- private EventTriggering eventTriggeringFlag = EventTriggering.TriggerAll;
- private string filename;
- private ImageHandler imageHandler;
- private bool invokeMSBuildWhenResumed;
- private bool isClosed;
- private bool isDirty;
- private bool isDisposed;
- private bool isNewProject;
- private bool isProjectEventsListener = true;
- /// <summary>
- /// Flag for controling how many times we register with the Scc manager.
- /// </summary>
- private bool isRegisteredWithScc;
- /// <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>
- /// A cached copy of project options.
- /// </summary>
- private ProjectOptions options;
- /// <summary>
- /// Member to store output base relative path. Used by OutputBaseRelativePath property
- /// </summary>
- private string outputBaseRelativePath = "bin";
- /// <summary>
- /// The internal package implementation.
- /// </summary>
- private ProjectPackage package;
- private IProjectEvents projectEventsProvider;
- private Guid projectIdGuid;
- private bool projectOpened;
- private string sccAuxPath;
- private string sccLocalPath;
- private string sccProjectName;
- private string sccProvider;
- private bool showProjectInSolutionPage = true;
- /// <summary>A service provider call back object provided by the IDE hosting the project manager</summary>
- private ServiceProvider site;
- /// <summary>
- /// Defines if Project System supports Project Designer
- /// </summary>
- private bool supportsProjectDesigner;
- private uint suspendMSBuildCounter;
- private TaskProvider taskProvider;
- /// <summary>
- /// Token processor used by the project sample.
- /// </summary>
- private TokenProcessor tokenProcessor;
- private TrackDocumentsHelper tracker;
- private bool useProvidedLogger;
- private string warningString;
- /// <summary>
- /// Used for flavoring to hold the XML fragments
- /// </summary>
- private XmlDocument xmlFragments;
- public static ServiceProvider ServiceProvider { get; set; }
- #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>
- [Browsable(false)]
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID")]
- public virtual Guid ProjectIDGuid
- {
- get { return projectIdGuid; }
- set
- {
- if (projectIdGuid != value)
- {
- projectIdGuid = value;
- if (buildProject != null)
- {
- SetProjectProperty("ProjectGuid", 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 GetMkDocument(); }
- }
- public override string Caption
- {
- get
- {
- // Default to file name
- string caption = buildProject.FullPath;
- if (String.IsNullOrEmpty(caption))
- {
- if (buildProject.GetProperty(ProjectFileConstants.Name) != null)
- {
- caption = buildProject.GetProperty(ProjectFileConstants.Name).EvaluatedValue;
- if (caption == null || caption.Length == 0)
- {
- caption = ItemNode.GetMetadata(ProjectFileConstants.Include);
- }
- }
- }
- else
- {
- caption = Path.GetFileNameWithoutExtension(caption);
- }
- return caption;
- }
- }
- public override Guid ItemTypeGuid
- {
- get { return ProjectGuid; }
- }
- public override int ImageIndex
- {
- get { return (int)ImageName.Application; }
- }
- #endregion
- #region virtual properties
- public virtual string ErrorString
- {
- get
- {
- if (errorString == null)
- {
- errorString = SR.GetString(SR.Error, CultureInfo.CurrentUICulture);
- }
- return errorString;
- }
- }
- public virtual string WarningString
- {
- get
- {
- if (warningString == null)
- {
- warningString = SR.GetString(SR.Warning, CultureInfo.CurrentUICulture);
- }
- return 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 = GetMkDocument();
- if (String.IsNullOrEmpty(document))
- {
- return isDirty;
- }
- return (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 supportsProjectDesigner; }
- set { 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 showProjectInSolutionPage; }
- set { 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 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 lastModifiedTime; }
- }
- /// <summary>
- /// Determines whether this project is a new project.
- /// </summary>
- public bool IsNewProject
- {
- get { return isNewProject; }
- }
- /// <summary>
- /// Gets the path to the folder containing the project.
- /// </summary>
- public string ProjectFolder
- {
- get { return Path.GetDirectoryName(filename); }
- }
- /// <summary>
- /// Gets or sets the project filename.
- /// </summary>
- public string ProjectFile
- {
- get { return Path.GetFileName(filename); }
- set { SetEditLabel(value); }
- }
- /// <summary>
- /// Gets the Base Uniform Resource Identifier (URI).
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "URI")]
- public Url BaseURI
- {
- get
- {
- if (baseUri == null && buildProject != null)
- {
- string path = Path.GetDirectoryName(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 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 outputBaseRelativePath; }
- set
- {
- if (Path.IsPathRooted(value))
- {
- throw new ArgumentException("Path must not be rooted.");
- }
- outputBaseRelativePath = value;
- }
- }
- public FrameworkName TargetFrameworkMoniker
- {
- get
- {
- if (options == null)
- {
- GetProjectOptions();
- }
- if (options != null)
- {
- return options.TargetFrameworkMoniker ?? DefaultTargetFrameworkMoniker;
- }
- else
- {
- return DefaultTargetFrameworkMoniker;
- }
- }
- set
- {
- if (options == null)
- {
- GetProjectOptions();
- }
- if (value == null)
- {
- value = DefaultTargetFrameworkMoniker;
- }
- if (options.TargetFrameworkMoniker != value)
- {
- OnTargetFrameworkMonikerChanged(options, options.TargetFrameworkMoniker, value);
- }
- }
- }
- /// <summary>
- /// Version of this node as an IVsHierarchy that can be safely passed to native code from a background thread.
- /// </summary>
- public IVsHierarchy InteropSafeIVsHierarchy { get; protected set; }
- /// <summary>
- /// Version of this node as an IVsUIHierarchy that can be safely passed to native code from a background thread.
- /// </summary>
- public IVsUIHierarchy InteropSafeIVsUIHierarchy { get; protected set; }
- /// <summary>
- /// Version of this node as an IVsProject3 that can be safely passed to native code from a background thread.
- /// </summary>
- public IVsProject3 InteropSafeIVsProject3 { get; protected set; }
- /// <summary>
- /// Version of this node as an IVsSccProject2 that can be safely passed to native code from a background thread.
- /// </summary>
- public IVsSccProject2 InteropSafeIVsSccProject2 { get; protected set; }
- /// <summary>
- /// Version of this node as an IVsUIHierWinClipboardHelperEvents that can be safely passed to native code from a background thread.
- /// </summary>
- public IVsUIHierWinClipboardHelperEvents InteropSafeIVsUIHierWinClipboardHelperEvents { get; protected set; }
- public IVsComponentUser InteropSafeIVsComponentUser { get; protected set; }
- /// <summary>
- /// Gets or sets the flag whether query edit should communicate with the scc manager.
- /// </summary>
- protected bool DisableQueryEdit
- {
- get { return disableQueryEdit; }
- set { disableQueryEdit = value; }
- }
- /// <summary>
- /// Gets a collection of integer ids that maps to project item instances
- /// </summary>
- internal EventSinkCollection ItemIdMap
- {
- get { return itemIdMap; }
- }
- /// <summary>
- /// Get the helper object that track document changes.
- /// </summary>
- internal TrackDocumentsHelper Tracker
- {
- get { return tracker; }
- }
- /// <summary>
- /// Gets or sets the build logger.
- /// </summary>
- protected Logger BuildLogger
- {
- get { return buildLogger; }
- set
- {
- buildLogger = value;
- useProvidedLogger = true;
- }
- }
- /// <summary>
- /// Gets the taskprovider.
- /// </summary>
- protected TaskProvider TaskProvider
- {
- get { return taskProvider; }
- }
- /// <summary>
- /// Gets the project file name.
- /// </summary>
- protected string FileName
- {
- get { return filename; }
- }
- protected bool IsIdeInCommandLineMode
- {
- get
- {
- bool cmdline = false;
- var shell = 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 (configProvider == null)
- {
- configProvider = CreateConfigProvider();
- }
- return 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 disableScc; }
- set { 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 projectOpened; }
- }
- /// <summary>
- /// Gets or sets event triggering flags.
- /// </summary>
- internal EventTriggering EventTriggeringFlag
- {
- get { return eventTriggeringFlag; }
- set { eventTriggeringFlag = value; }
- }
- /// <summary>
- /// Defines the build project that has loaded the project file.
- /// </summary>
- protected internal MSBuild.Project BuildProject
- {
- get { return buildProject; }
- set { SetBuildProject(value); }
- }
- /// <summary>
- /// Gets the current config.
- /// </summary>
- /// <value>The current config.</value>
- protected internal ProjectInstance CurrentConfig
- {
- get { return currentConfig; }
- }
- /// <summary>
- /// Defines the build engine that is used to build the project file.
- /// </summary>
- internal ProjectCollection BuildEngine
- {
- get { return buildEngine; }
- set { buildEngine = value; }
- }
- /// <summary>
- /// The internal package implementation.
- /// </summary>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal ProjectPackage Package
- {
- get { return package; }
- set { package = value; }
- }
- #endregion
- #region ctor
- protected ProjectNode()
- {
- 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:
- 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 (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(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(Url))
- {
- throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
- SR.GetString(SR.FileOrFolderCannotBeFound,
- CultureInfo.CurrentUICulture),
- ProjectFile));
- }
- // Get the full file name and then rename the project file.
- string newFile = Path.Combine(ProjectFolder, label);
- string extension = Path.GetExtension(Url);
- // Make sure it has the correct extension
- if (String.Compare(Path.GetExtension(newFile), extension, StringComparison.OrdinalIgnoreCase) != 0)
- {
- newFile += extension;
- }
- 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 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
- {
- Dispose(true);
- }
- }
- catch (COMException e)
- {
- hr = e.ErrorCode;
- }
- finally
- {
- ErrorHandler.ThrowOnFailure(base.Close());
- }
- 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(IOleServiceProvider 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 ConfigProvider;
- case __VSHPROPID.VSHPROPID_ProjectName:
- return Caption;
- case __VSHPROPID.VSHPROPID_ProjectDir:
- return ProjectFolder;
- case __VSHPROPID.VSHPROPID_TypeName:
- return ProjectType;
- case __VSHPROPID.VSHPROPID_ShowProjInSolutionPage:
- return 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 SupportsProjectDesigner;
- case __VSHPROPID2.VSHPROPID_PropertyPagesCLSIDList:
- return
- Utilities.CreateSemicolonDelimitedListOfStringFromGuids(
- GetConfigurationIndependentPropertyPages());
- case __VSHPROPID2.VSHPROPID_CfgPropertyPagesCLSIDList:
- return
- Utilities.CreateSemicolonDelimitedListOfStringFromGuids(GetConfigurationDependentPropertyPages());
- case __VSHPROPID2.VSHPROPID_PriorityPropertyPagesCLSIDList:
- return Utilities.CreateSemicolonDelimitedListOfStringFromGuids(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 = ProjectIDGuid;
- }
- else if (propid == (int)__VSHPROPID.VSHPROPID_CmdUIGuid)
- {
- guid = ProjectGuid;
- }
- else if ((__VSHPROPID2)propid == __VSHPROPID2.VSHPROPID_ProjectDesignerEditor && SupportsProjectDesigner)
- {
- guid = 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:
- 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 = Site.GetService(typeof(SVsSolution)) as IVsSolution;
- uint iOption = 1; // SLNSAVEOPT_PromptSave
- ErrorHandler.ThrowOnFailure(solution.CloseSolutionElement(iOption, InteropSafeIVsHierarchy, 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(filename));
- Debug.Assert(BaseURI != null && !String.IsNullOrEmpty(BaseURI.AbsoluteUrl));
- return Path.Combine(BaseURI.AbsoluteUrl, 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 (isDisposed)
- {
- return;
- }
- try
- {
- try
- {
- UnRegisterProject();
- }
- finally
- {
- try
- {
- RegisterClipboardNotifications(false);
- }
- finally
- {
- try
- {
- if (projectEventsProvider != null)
- {
- projectEventsProvider.AfterProjectFileOpened -= OnAfterProjectOpen;
- }
- if (taskProvider != null)
- {
- taskProvider.Tasks.Clear();
- taskProvider.Dispose();
- taskProvider = null;
- }
- if (buildLogger != null)
- {
- buildLogger.Shutdown();
- buildLogger = null;
- }
- if (site != null)
- {
- site.Dispose();
- }
- }
- finally
- {
- buildEngine = null;
- }
- }
- }
- if (buildProject != null)
- {
- buildProject.ProjectCollection.UnloadProject(buildProject);
- buildProject.ProjectCollection.UnloadProject(buildProject.Xml);
- buildProject = null;
- }
- if (null != imageHandler)
- {
- imageHandler.Close();
- imageHandler = null;
- }
- }
- finally
- {
- base.Dispose(disposing);
- 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 (HasDesigner)
- {
- result |= QueryStatusResult.SUPPORTED | QueryStatusResult.ENABLED;
- return VSConstants.S_OK;
- }
- break;
- case VsCommands.CancelBuild:
- result |= QueryStatusResult.SUPPORTED;
- if (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 be NULL.</param>
- /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
- protected override int ExecCommandOnNode(Guid cmdGroup, uint cmd, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
- {
- if (cmdGroup == VsMenus.guidStandardCommandSet97)
- {
- switch ((VsCommands)cmd)
- {
- case VsCommands.UnloadProject:
- return UnloadProject();
- case VsCommands.CleanSel:
- case VsCommands.CleanCtx:
- …
Large files files are truncated, but you can click here to view the full file