GenerateTemporaryTargetAssembly.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Build / Microsoft / Build / Tasks / Windows / GenerateTemporaryTargetAssembly.cs / 1 / GenerateTemporaryTargetAssembly.cs

                             
//----------------------------------------------------------------------------
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved. 
// 
// 
// Description: This is a MSBuild task which generates a temporary target assembly 
//              if current project contains a xaml file with local-type-reference.
// 
//              It generates a temporary project file and then call build-engine
//              to compile it.
//
//              The new project file will replace all the Reference Items with the 
//              resolved ReferenctPath, add all the generated code file into Compile
//              Item list. 
// 
// History:
//  05/10/05: [....]   Created. 
//
//---------------------------------------------------------------------------

using System; 
using System.IO;
using System.Collections; 
 
using System.Globalization;
using System.Diagnostics; 
using System.Reflection;
using System.Resources;
using System.Xml;
 
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities; 
using Microsoft.Build.BuildEngine; 

using MS.Utility; 
using MS.Internal.Tasks;

// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler.
// We first need to disable warnings about unknown message numbers and unknown pragmas. 
#pragma warning disable 1634, 1691
 
namespace Microsoft.Build.Tasks.Windows 
{
    #region GenerateTemporaryTargetAssembly Task class 

    /// 
    ///   This task is used to generate a temporary target assembly. It generates
    ///   a temporary project file and then compile it. 
    ///
    ///   The generated project file is based on current project file, with below 
    ///   modification: 
    ///
    ///       A:  Add the generated code files (.g.cs) to Compile Item list. 
    ///       B:  Replace Reference Item list with ReferenctPath item list.
    ///           So that it doesn't need to rerun time-consuming tatk
    ///           ResolveAssemblyReference (RAR) again.
    /// 
    /// 
    public sealed class GenerateTemporaryTargetAssembly : Task 
    { 
        //-----------------------------------------------------
        // 
        //  Constructors
        //
        //-----------------------------------------------------
 
        #region Constructors
 
        ///  
        /// Constrcutor
        ///  
        public GenerateTemporaryTargetAssembly()
            : base(SR.ResourceManager)
        {
        } 

        #endregion Constructors 
 
        //------------------------------------------------------
        // 
        //  Public Methods
        //
        //-----------------------------------------------------
 
        #region Public Methods
 
        ///  
        /// ITask Execute method
        ///  
        /// 
        public override bool Execute()
        {
            bool retValue = true; 

            // Verification 
            try 
            {
                XmlDocument xmlProjectDoc = null; 

                xmlProjectDoc = new XmlDocument( );
                xmlProjectDoc.Load(CurrentProject);
 
                //
                // remove all the WinFX specific item lists 
                // ApplicationDefinition, Page, MarkupResource and Resource 
                //
 
                RemoveItemsByName(xmlProjectDoc, APPDEFNAME);
                RemoveItemsByName(xmlProjectDoc, PAGENAME);
                RemoveItemsByName(xmlProjectDoc, MARKUPRESOURCENAME);
                RemoveItemsByName(xmlProjectDoc, RESOURCENAME); 

                // Replace the Reference Item list with ReferencePath 
 
                RemoveItemsByName(xmlProjectDoc, REFERENCETYPENAME);
                AddNewItems(xmlProjectDoc, ReferencePathTypeName, ReferencePath); 

                // Add GeneratedCodeFiles to Compile item list.
                AddNewItems(xmlProjectDoc, CompileTypeName, GeneratedCodeFiles);
 

                // Create a random file name 
                // This can fix the problem of project cache in VS.NET environment. 
                //
 
                // GetRandomFileName( ) could return any possible file name and extension, but
                // some file externsion has special meaning in MSBUILD system, such as a ".sln"
                // means the file is a solution file with special file format. Since the temporary
                // file is just for a project, we can use a fixed extension here, but the basic 
                // file name is still random which can fix above VS.NET bug.
                // 
                string randProj = Path.ChangeExtension(Path.GetRandomFileName(), TEMP_PROJ_EXT); 

                // Save the xmlDocument content into the temporary project file. 
                xmlProjectDoc.Save(randProj);

                //
                // Invoke MSBUILD engine to build this temporary project file. 
                //
 
                Hashtable globalProperties = new Hashtable(2); 

                // Add AssemblyName and IntermediateOutputPath to the global property list 
                globalProperties[intermediateOutputPathPropertyName] = IntermediateOutputPath;
                globalProperties[assemblyNamePropertyName] = AssemblyName;

                retValue = BuildEngine.BuildProjectFile(randProj, new string[] { CompileTargetName }, globalProperties, null); 

                // Delete the random project file from disk. 
                File.Delete(randProj); 

            } 
#pragma warning disable 6500
            catch (Exception e)
            {
                Log.LogErrorFromException(e); 
                retValue = false;
            } 
#pragma warning retore 6500 

            return retValue; 
        }

        #endregion Public Methods
 
        //------------------------------------------------------
        // 
        //  Public Properties 
        //
        //------------------------------------------------------ 

        #region Public Properties

        ///  
        /// CurrentProject
        ///    The full path of current project file. 
        ///  
        [Required]
        public string  CurrentProject 
        {
            get { return _currentProject; }
            set { _currentProject = value; }
        } 

        ///  
        /// MSBuild Binary Path. 
        ///   This is required for Project to work correctly.
        ///  
        [Required]
        public string MSBuildBinPath
        {
            get { return _msbuildBinPath; } 
            set { _msbuildBinPath = value; }
        } 
 
        /// 
        /// GeneratedCodeFiles 
        ///    A list of generated code files, it could be empty.
        ///    The list will be added to the Compile item list in new generated project file.
        /// 
        public ITaskItem[] GeneratedCodeFiles 
        {
            get { return _generatedCodeFiles; } 
            set { _generatedCodeFiles = value; } 
        }
 
        /// 
        /// CompileTypeName
        ///   The appropriate item name which can be accepted by managed compiler task.
        ///   It is "Compile" for now. 
        ///
        ///   Adding this property is to make the type name configurable, if it is changed, 
        ///   No code is required to change in this task, but set a new type name in project file. 
        /// 
        [Required] 
        public string CompileTypeName
        {
            get { return _compileTypeName; }
            set { _compileTypeName = value; } 
        }
 
 
        /// 
        /// ReferencePath 
        ///    A list of resolved reference assemblies.
        ///    The list will replace the original Reference item list in generated project file.
        /// 
        public ITaskItem[] ReferencePath 
        {
            get { return _referencePath; } 
            set { _referencePath = value; } 
        }
 
        /// 
        /// ReferencePathTypeName
        ///   The appropriate item name which is used to keep the Reference list in managed compiler task.
        ///   It is "ReferencePath" for now. 
        ///
        ///   Adding this property is to make the type name configurable, if it is changed, 
        ///   No code is required to change in this task, but set a new type name in project file. 
        /// 
        [Required] 
        public string ReferencePathTypeName
        {
            get { return _referencePathTypeName; }
            set { _referencePathTypeName = value; } 
        }
 
 
        /// 
        /// IntermediateOutputPath 
        ///
        /// The value which is set to IntermediateOutputPath property in current project file.
        ///
        /// Passing this value explicitly is to make sure to generate temporary target assembly 
        /// in expected directory.
        ///  
        [Required] 
        public string IntermediateOutputPath
        { 
            get { return _intermediateOutputPath; }
            set { _intermediateOutputPath = value; }
        }
 
        /// 
        /// AssemblyName 
        /// 
        /// The value which is set to AssemblyName property in current project file.
        /// Passing this value explicitly is to make sure to generate the expected 
        /// temporary target assembly.
        ///
        /// 
        [Required] 
        public string AssemblyName
        { 
            get { return _assemblyName; } 
            set { _assemblyName = value; }
        } 

        /// 
        /// CompileTargetName
        /// 
        /// The msbuild target name which is used to generate assembly from source code files.
        /// Usually it is "CoreCompile" 
        /// 
        /// 
        [Required] 
        public string CompileTargetName
        {
            get { return _compileTargetName; }
            set { _compileTargetName = value; } 
        }
 
        #endregion Public Properties 

        //----------------------------------------------------- 
        //
        //  Private Methods
        //
        //------------------------------------------------------ 

        #region Private Methods 
 
        //
        // Remove specific items from project file. Every item should be under an ItemGroup. 
        //
        private void RemoveItemsByName(XmlDocument xmlProjectDoc, string sItemName)
        {
            if (xmlProjectDoc == null || String.IsNullOrEmpty(sItemName)) 
            {
                // When the parameters are not valid, simply return it, instead of throwing exceptions. 
                return; 
            }
 
            //
            // The project file format is always like below:
            //
            //   
            //     
            //         ...... 
            //      
            //
            //     ... 
            //     
            //         
            //         ....
            //      
            //
            //     .... 
            //      
            //     ...
            //      
            //
            //      ...
            //
            //   
            //
            // 
            // The order of children nodes under Project Root element is random 
            //
 
            XmlNode root = xmlProjectDoc.DocumentElement;

            if (root.HasChildNodes == false)
            { 
                // If there is no child element in this project file, just return immediatelly.
                return; 
            } 

            for (int i = 0; i < root.ChildNodes.Count; i++) 
            {
                XmlElement nodeGroup = root.ChildNodes[i] as XmlElement;

                if (nodeGroup != null && String.Compare(nodeGroup.Name, ITEMGROUP_NAME, StringComparison.OrdinalIgnoreCase) == 0) 
                {
                    // 
                    // This is ItemGroup element. 
                    //
                    if (nodeGroup.HasChildNodes) 
                    {
                        ArrayList itemToRemove = new ArrayList();

                        for (int j = 0; j < nodeGroup.ChildNodes.Count; j++) 
                        {
                            XmlElement nodeItem = nodeGroup.ChildNodes[j] as XmlElement; 
 
                            if (nodeItem != null && String.Compare(nodeItem.Name, sItemName, StringComparison.OrdinalIgnoreCase) == 0)
                            { 
                                // This is the item that need to remove.
                                // Add it into the temporary array list.
                                // Don't delete it here, since it would affect the ChildNodes of parent element.
                                // 
                                itemToRemove.Add(nodeItem);
                            } 
                        } 

                        // 
                        // Now it is the right time to delete the elements.
                        //
                        if (itemToRemove.Count > 0)
                        { 
                            foreach (object node in itemToRemove)
                            { 
                                XmlElement item = node as XmlElement; 

                                // 
                                // Remove this item from its parent node.
                                // the parent node should be nodeGroup.
                                //
                                if (item != null) 
                                {
                                    nodeGroup.RemoveChild(item); 
                                } 
                            }
                        } 
                    }

                    //
                    // Removed all the items with given name from this item group. 
                    //
                    // Continue the loop for the next ItemGroup. 
                } 

            }   // end of "for i" statement. 

        }

        // 
        // Add a list of files into an Item in the project file, the ItemName is specified by sItemName.
        // 
        private void AddNewItems(XmlDocument xmlProjectDoc, string sItemName, ITaskItem[] pItemList) 
        {
            if (xmlProjectDoc == null || String.IsNullOrEmpty(sItemName) || pItemList == null) 
            {
                // When the parameters are not valid, simply return it, instead of throwing exceptions.
                return;
            } 

            XmlNode root = xmlProjectDoc.DocumentElement; 
 
            // Create a new ItemGroup element
            XmlNode nodeItemGroup = xmlProjectDoc.CreateElement(ITEMGROUP_NAME, root.NamespaceURI); 

            // Append this new ItemGroup item into the list of children of the document root.
            root.AppendChild(nodeItemGroup);
 
            for (int i = 0; i < pItemList.Length; i++)
            { 
                // Create an element for the given sItemName 
                XmlElement nodeItem = xmlProjectDoc.CreateElement(sItemName, root.NamespaceURI);
 
                // Create an Attribute "Include"
                XmlAttribute attrInclude = xmlProjectDoc.CreateAttribute(INCLUDE_ATTR_NAME);

                // Set the value for Include attribute. 
                attrInclude.Value = pItemList[i].ItemSpec;
 
                // Add the attribute to current item node. 
                nodeItem.SetAttributeNode(attrInclude);
 
                // Add current item node into the children list of ItemGroup
                nodeItemGroup.AppendChild(nodeItem);
            }
        } 

        #endregion Private Methods 
 

        //----------------------------------------------------- 
        //
        //  Private Fields
        //
        //----------------------------------------------------- 

        #region Private Fields 
 
        private string _currentProject = String.Empty;
 
        private ITaskItem[] _generatedCodeFiles;
        private ITaskItem[] _referencePath;

        private string _referencePathTypeName; 
        private string _compileTypeName;
 
        private string _msbuildBinPath; 

        private string  _intermediateOutputPath; 
        private string  _assemblyName;
        private string  _compileTargetName;

        private const string intermediateOutputPathPropertyName = "IntermediateOutputPath"; 
        private const string assemblyNamePropertyName = "AssemblyName";
 
        private const string REFERENCETYPENAME = "Reference"; 
        private const string APPDEFNAME = "ApplicationDefinition";
        private const string PAGENAME = "Page"; 
        private const string MARKUPRESOURCENAME = "MarkupResource";
        private const string RESOURCENAME = "Resource";

        private const string ITEMGROUP_NAME = "ItemGroup"; 
        private const string INCLUDE_ATTR_NAME = "Include";
 
        private const string TEMP_PROJ_EXT = ".tmp_proj"; 

        #endregion Private Fields 

    }

    #endregion GenerateProjectForLocalTypeReference Task class 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK