globalpropertyhandler.cs :  » Installers-Generators » WiX » Microsoft » VisualStudio » Package » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Installers Generators » WiX 
WiX » Microsoft » VisualStudio » Package » globalpropertyhandler.cs
/***************************************************************************

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.

***************************************************************************/
namespace Microsoft.VisualStudio.Package{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using Microsoft.VisualStudio.Shell.Interop;
    using Microsoft.Win32;

    using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
    using IServiceProvider = System.IServiceProvider;
    using MSBuild = Microsoft.Build.BuildEngine;
#if !VS2005
    using VSRegistry = Microsoft.VisualStudio.Shell.VSRegistry;
#endif

    /// <summary>
    /// This class defines and sets the so called global properties that are needed to be provided
    /// before a project builds.
    /// </summary>
    internal class GlobalPropertyHandler : IDisposable
    {
        #region constants
        /// <summary>
        /// The registry relative path entry for finding the fxcop installdir
        /// </summary>
        private const string FxCopRegistryRelativePathEntry = "Setup\\EDev";

        /// <summary>
        /// The registry installation Directory key name.
        /// </summary>
        private const string FxCopRegistryInstallDirKeyName = "FxCopDir";

        /// <summary>
        /// This is the constant that will be set as the value of the VSIDEResolvedNonMSBuildProjectOutputs global property.
        /// </summary>
        private const string VSIDEResolvedNonMSBuildProjectOutputsValue = "<VSIDEResolvedNonMSBuildProjectOutputs></VSIDEResolvedNonMSBuildProjectOutputs>";


        #endregion

        #region fields
        /// <summary>
        /// Raised when the active project configuration for a project in the solution has changed. 
        /// </summary>
        internal event EventHandler<ActiveConfigurationChangedEventArgs> ActiveConfigurationChanged;

        /// <summary>
        /// Defines the global properties of the associated build project.
        /// </summary>
        private MSBuild.BuildPropertyGroup globalProjectProperties;

        /// <summary>
        /// Defines the global properties of the associated build engine.
        /// </summary>
        private MSBuild.BuildPropertyGroup globalEngineProperties;

        /// <summary>
        /// Flag determining if the object has been disposed.
        /// </summary>
        private bool isDisposed;

        /// <summary>
        /// Defines an object that will be a mutex for this object for synchronizing thread calls.
        /// </summary>
        private static volatile object Mutex = new object();

#if !VS2005
        /// <summary>
        /// Defines the configuration change listener.
        /// </summary>
        private UpdateConfigPropertiesListener configurationChangeListener;
#endif
        #endregion

        #region constructors
        /// <summary>
        /// Overloaded constructor.
        /// </summary>
        /// <param name="project">An instance of a build project</param>
        /// <exception cref="ArgumentNullException">Is thrown if the passed Project is null.</exception>
        internal GlobalPropertyHandler(MSBuild.Project project)
        {
            Debug.Assert(project != null, "The project parameter passed cannot be null");

            this.globalProjectProperties = project.GlobalProperties;

            Debug.Assert(project.ParentEngine != null, "The parent engine has not been initialized");

            this.globalEngineProperties = project.ParentEngine.GlobalProperties;
        }
        #endregion

        #region IDisposable Members

        /// <summary>
        /// The IDispose interface Dispose method for disposing the object determinastically.
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion

        #region methods
        /// <summary>
        /// Initializes MSBuild project properties. This method is called before the first project re-evaluation happens in order to set the global properties.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")]
        internal virtual void InitializeGlobalProperties()
        {

            // Set the BuildingInsideVisualStudio property to true.
            this.SetGlobalProperty(GlobalProperty.BuildingInsideVisualStudio.ToString(), "true");

            // Set the ResolvedNonMSBuildProjectOutputs property to empty.  This is so that it has some deterministic value, even
            // if it's empty.  This is important because of the way global properties are merged together when one
            // project is calling the <MSBuild> task on another project.  
            this.SetGlobalProperty(GlobalProperty.VSIDEResolvedNonMSBuildProjectOutputs.ToString(), VSIDEResolvedNonMSBuildProjectOutputsValue);

            // Set the RunCodeAnalysisOverride property to false.  This is so that it has some deterministic value.
            // This is important because of the way global properties are merged together when one
            // project is calling the <MSBuild> task on another project. 
            this.SetGlobalProperty(GlobalProperty.RunCodeAnalysisOnce.ToString(), "false");

            // Set Configuration=Debug.  This is a perf optimization, not strictly required for correct functionality.
            // Since most people keep most of their projects with Active Configuration = "Debug" during development,
            // setting this up front makes it faster to load the project.  This way, we don't have to change the
            // value of Configuration down the road, forcing MSBuild to have to re-evaluate the project.
            this.SetGlobalProperty(GlobalProperty.Configuration.ToString(), ProjectConfig.Debug);

            // Set Platform=AnyCPU.  This is a perf optimization, not strictly required for correct functionality.
            // Since most people keep most of their projects with Active Platform = "AnyCPU" during development,
            // setting this up front makes it faster to load the project.  This way, we don't have to change the
            // value of Platform down the road, forcing MSBuild to have to re-evaluate the project.
            this.SetGlobalProperty(GlobalProperty.Platform.ToString(), ProjectConfig.AnyCPU);

            // Set the solution related msbuild global properties.
            this.SetSolutionProperties();

            // Set the VS location global property.
            this.SetGlobalProperty(GlobalProperty.DevEnvDir.ToString(), GetEnvironmentDirectoryLocation());

            // Set the fxcop location global property.
            this.SetGlobalProperty(GlobalProperty.FxCopDir.ToString(), GetFxCopDirectoryLocation());
        }

        /// <summary>
        /// Initializes the internal configuration change listener.
        /// </summary>
        /// <param name="hierarchy">The associated service hierarchy.</param>
        /// <param name="serviceProvider">The associated service provider.</param>
        internal void RegisterConfigurationChangeListener(IVsHierarchy hierarchy, IServiceProvider serviceProvider)
        {
            Debug.Assert(hierarchy != null, "The passed hierarchy cannot be null");
            Debug.Assert(serviceProvider != null, "The passed service provider cannot be null");
#if !VS2005
            Debug.Assert(this.configurationChangeListener == null, "The configuration change listener has already been initialized");
            this.configurationChangeListener = new UpdateConfigPropertiesListener(this, hierarchy, serviceProvider);
#endif
        }

        /// <summary>
        /// The method that does the cleanup.
        /// </summary>
        /// <param name="disposing">true if called from IDispose.Dispose; false if called from Finalizer.</param>
        protected virtual void Dispose(bool disposing)
        {
            // Everybody can go here.
            if (!this.isDisposed)
            {
                // Synchronize calls to the Dispose simultaniously.
                lock (Mutex)
                {
                    if (disposing)
                    {
#if !VS2005
                        this.configurationChangeListener.Dispose();
#endif
                    }

                    this.isDisposed = true;
                }
            }
        }

        /// <summary>
        /// Called when the active project configuration for a project in the solution has changed. 
        /// </summary>
        /// <param name="hierarchy">The project whose configuration has changed.</param>
        private void RaiseActiveConfigurationChanged(IVsHierarchy hierarchy)
        {
            // Save event in temporary variable to avoid race condition.
            EventHandler<ActiveConfigurationChangedEventArgs> tempEvent = this.ActiveConfigurationChanged;
            if (tempEvent != null)
            {
                tempEvent(this, new ActiveConfigurationChangedEventArgs(hierarchy));
            }
        }

        /// <summary>
        /// Sets the solution related global properties (SolutionName, SolutionFileName, SolutionPath, SolutionDir, SolutionExt).
        /// </summary>
        private void SetSolutionProperties()
        {
            IVsSolution solution = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(IVsSolution)) as IVsSolution;
            Debug.Assert(solution != null, "Could not retrieve the solution service from the global service provider");

            string solutionDirectory, solutionFile, userOptionsFile;

            // We do not want to throw. If we cannot set the solution related constants we set them to empty string.
            solution.GetSolutionInfo(out solutionDirectory, out solutionFile, out userOptionsFile);

            if (solutionDirectory == null)
            {
                solutionDirectory = String.Empty;
            }

            this.SetGlobalProperty(GlobalProperty.SolutionDir.ToString(), solutionDirectory);

            if (solutionFile == null)
            {
                solutionFile = String.Empty;
            }

            this.SetGlobalProperty(GlobalProperty.SolutionPath.ToString(), solutionFile);

            string solutionFileName = (solutionFile.Length == 0) ? String.Empty : Path.GetFileName(solutionFile);
            this.SetGlobalProperty(GlobalProperty.SolutionFileName.ToString(), solutionFileName);

            string solutionName = (solutionFile.Length == 0) ? String.Empty : Path.GetFileNameWithoutExtension(solutionFile);
            this.SetGlobalProperty(GlobalProperty.SolutionName.ToString(), solutionName);

            string solutionExtension = String.Empty;
            if (solutionFile.Length > 0 && Path.HasExtension(solutionFile))
            {
                solutionExtension = Path.GetExtension(solutionFile);
            }

            this.SetGlobalProperty(GlobalProperty.SolutionExt.ToString(), solutionExtension);
        }

        /// <summary>
        /// Retrieves the Devenv installation directory.
        /// </summary>
        private static string GetEnvironmentDirectoryLocation()
        {
            IVsShell shell = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(IVsShell)) as IVsShell;
            Debug.Assert(shell != null, "Could not retrieve the IVsShell service from the global service provider");

            object installDirAsObject;

            // We do not want to throw. If we cannot set the solution related constants we set them to empty string.
            shell.GetProperty((int)__VSSPROPID.VSSPROPID_InstallDirectory, out installDirAsObject);

            string installDir = ((string)installDirAsObject);

            if (String.IsNullOrEmpty(installDir))
            {
                return String.Empty;
            }

            // Ensure that we have traimnling backslash as this is done for the langproj macros too.
            if (installDir[installDir.Length - 1] != Path.DirectorySeparatorChar)
            {
                installDir += Path.DirectorySeparatorChar;
            }

            return installDir;
        }


        /// <summary>
        /// Retrieves the fxcop dierctory location
        /// </summary>
        private static string GetFxCopDirectoryLocation()
        {
#if !VS2005
            using (RegistryKey root = VSRegistry.RegistryRoot(__VsLocalRegistryType.RegType_Configuration))
            {
                if (null == root)
                {
                    return String.Empty;
                }

                using (RegistryKey key = root.OpenSubKey(FxCopRegistryRelativePathEntry))
                {
                    if (key != null)
                    {
                        string fxcopInstallDir = key.GetValue(FxCopRegistryInstallDirKeyName) as string;

                        return (fxcopInstallDir == null) ? String.Empty : fxcopInstallDir;
                    }
                }
            }
#endif

            return String.Empty;
        }

        /// <summary>
        /// Sets a global property on the associated build project and build engine.
        /// </summary>
        /// <param name="propertyName">The name of teh property to set.</param>
        /// <param name="propertyValue">Teh value of teh property.</param>
        private void SetGlobalProperty(string propertyName, string propertyValue)
        {
            this.globalProjectProperties.SetProperty(propertyName, propertyValue, true);

            // Set the same global property on the parent Engine object.  The Project
            // object, when it was created, got a clone of the global properties from
            // the engine.  So changing it in the Project doesn't impact the Engine.
            // However, we do need the Engine to have this new global property setting
            // as well, because with project-to-project references, any child projects
            // are going to get their initial global properties from the Engine when
            // they are created.
            this.globalEngineProperties.SetProperty(propertyName, propertyValue, true);
        }
        #endregion

        #region nested types
#if !VS2005
        /// <summary>
        /// Defines a class that will listen to configuration changes and will update platform and configuration name changes accordingly.
        /// </summary>
        private class UpdateConfigPropertiesListener : UpdateSolutionEventsListener
        {
            #region fields
            /// <summary>
            /// The hierarchy that is associated to a configuration or platform change.
            /// </summary>
            private IVsHierarchy associatedHierarchy;

            /// <summary>
            /// Defines the containing object.
            /// </summary>
            private GlobalPropertyHandler globalPropertyHandler;
            #endregion

            #region constructors
            /// <summary>
            /// Overloaded constructor.
            /// </summary>
            /// <param name="globalProperties"></param>
            /// <param name="associatedHierachy">The associated hierrachy.</param>
            /// <param name="serviceProvider">The associated service provider</param>
            internal UpdateConfigPropertiesListener(GlobalPropertyHandler globalPropertyHandler, IVsHierarchy associatedHierarchy, IServiceProvider serviceProvider)
                : base(serviceProvider)
            {
                this.globalPropertyHandler = globalPropertyHandler;
                this.associatedHierarchy = associatedHierarchy;
            }
            #endregion

            #region methods
            /// <summary>
            /// Called when the active project configuration for a project in the solution has changed. 
            /// </summary>
            /// <param name="hierarchy">The project whose configuration has changed.</param>
            /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
            public override int OnActiveProjectCfgChange(IVsHierarchy hierarchy)
            {
                this.globalPropertyHandler.RaiseActiveConfigurationChanged(hierarchy);
                return VSConstants.S_OK;
            }
            #endregion
        }
#endif
        #endregion
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.