Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / BuildTasks / Microsoft / Build / Tasks / Windows / GenerateTemporaryTargetAssembly.cs / 1305600 / 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: weibz 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);
if (TRUE == pItemList[i].GetMetadata(EMBEDINTEROPTYPES))
{
XmlElement embedItem = xmlProjectDoc.CreateElement(EMBEDINTEROPTYPES, root.NamespaceURI);
embedItem.InnerText = TRUE;
nodeItem.AppendChild(embedItem);
}
// 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 EMBEDINTEROPTYPES = "EmbedInteropTypes";
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 TRUE = "True";
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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PrePostDescendentsWalker.cs
- RepeaterCommandEventArgs.cs
- Type.cs
- UserControl.cs
- SmiRequestExecutor.cs
- Base64Encoder.cs
- ConfigurationElement.cs
- IncrementalReadDecoders.cs
- EditorResources.cs
- StreamWithDictionary.cs
- OpenFileDialog.cs
- MexTcpBindingCollectionElement.cs
- QueueException.cs
- PropertyAccessVisitor.cs
- RefreshPropertiesAttribute.cs
- LoaderAllocator.cs
- ProfileEventArgs.cs
- CompilerWrapper.cs
- BrowserCapabilitiesCompiler.cs
- MembershipUser.cs
- SlipBehavior.cs
- _ListenerResponseStream.cs
- SerializationSectionGroup.cs
- HTMLTagNameToTypeMapper.cs
- AnnouncementSendsAsyncResult.cs
- CharKeyFrameCollection.cs
- ProxyRpc.cs
- WebPartDeleteVerb.cs
- PropertyInformationCollection.cs
- SslStream.cs
- Enum.cs
- IntSecurity.cs
- PointConverter.cs
- BufferedMessageWriter.cs
- CssTextWriter.cs
- NoPersistScope.cs
- MarkupCompilePass2.cs
- OutputChannel.cs
- DefaultMemberAttribute.cs
- RegexStringValidator.cs
- RenderDataDrawingContext.cs
- XmlDocument.cs
- DataFormats.cs
- ReadWriteObjectLock.cs
- Property.cs
- MetroSerializationManager.cs
- InteropDesigner.xaml.cs
- TextRangeEdit.cs
- Polyline.cs
- TemplateControlCodeDomTreeGenerator.cs
- ToolStripDropDownButton.cs
- SmuggledIUnknown.cs
- QueryOperationResponseOfT.cs
- XmlComment.cs
- WebEvents.cs
- CachingHintValidation.cs
- CodeDOMUtility.cs
- XmlSerializerNamespaces.cs
- XmlSchemaAttributeGroupRef.cs
- OletxCommittableTransaction.cs
- QueryGeneratorBase.cs
- PageCache.cs
- XmlSchemaProviderAttribute.cs
- SrgsElementFactory.cs
- FocusWithinProperty.cs
- PasswordBox.cs
- CommandField.cs
- SamlSerializer.cs
- AnimatedTypeHelpers.cs
- ImportOptions.cs
- NameValueFileSectionHandler.cs
- UICuesEvent.cs
- MatrixKeyFrameCollection.cs
- SynchronizationLockException.cs
- AppSecurityManager.cs
- XMLUtil.cs
- AdjustableArrowCap.cs
- MessageDecoder.cs
- WsdlContractConversionContext.cs
- MailHeaderInfo.cs
- ConsoleTraceListener.cs
- SizeIndependentAnimationStorage.cs
- DesignParameter.cs
- TableLayoutStyle.cs
- Utils.cs
- BamlLocalizableResourceKey.cs
- DiffuseMaterial.cs
- SettingsPropertyIsReadOnlyException.cs
- TraceHandlerErrorFormatter.cs
- ComboBoxAutomationPeer.cs
- FactoryMaker.cs
- XmlCharType.cs
- NullToBooleanConverter.cs
- Char.cs
- LexicalChunk.cs
- StylusLogic.cs
- DataObjectFieldAttribute.cs
- WebPartConnectVerb.cs
- TemplateBamlRecordReader.cs
- ConnectionProviderAttribute.cs