public void TestLoadXml() { TaskParser tp = new TaskParser(); string s = @"<ProjectSchemaDefinitions xmlns=`clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework` xmlns:x=`http://schemas.microsoft.com/winfx/2006/xaml` xmlns:sys=`clr-namespace:System;assembly=mscorlib` xmlns:impl=`clr-namespace:Microsoft.VisualStudio.Project.Contracts.Implementation;assembly=Microsoft.VisualStudio.Project.Contracts.Implementation`> <Rule Name=`TaskGeneratorLoadTest`> <BoolProperty Name=`TestProperty1` Switch=`tp` /> </Rule> </ProjectSchemaDefinitions>"; Assert.True(tp.Parse(s.Replace("`", "\""), "TaskGeneratorLoadTest")); // "File failed to load correctly." }
public bool Initialize(string taskName, IDictionary<string, TaskPropertyInfo> taskParameters, string taskElementContents, IBuildEngine taskFactoryLoggingHost) { CompilerResults results; Microsoft.Build.Shared.ErrorUtilities.VerifyThrowArgumentNull(taskName, "taskName"); Microsoft.Build.Shared.ErrorUtilities.VerifyThrowArgumentNull(taskParameters, "taskParameters"); TaskLoggingHelper helper = new TaskLoggingHelper(taskFactoryLoggingHost, taskName) { TaskResources = Microsoft.Build.Shared.AssemblyResources.PrimaryResources, HelpKeywordPrefix = "MSBuild." }; if (taskElementContents == null) { helper.LogErrorWithCodeFromResources("Xaml.MissingTaskBody", new object[0]); return false; } this.TaskElementContents = taskElementContents.Trim(); TaskParser parser = new TaskParser(); parser.Parse(this.TaskElementContents, taskName); this.TaskName = parser.GeneratedTaskName; this.TaskNamespace = parser.Namespace; CodeCompileUnit compileUnit = new TaskGenerator(parser).GenerateCode(); Assembly assembly = Assembly.LoadWithPartialName("System"); Assembly assembly2 = Assembly.LoadWithPartialName("Microsoft.Build.Framework"); Assembly assembly3 = Assembly.LoadWithPartialName("Microsoft.Build.Utilities.V4.0"); Assembly assembly4 = Assembly.LoadWithPartialName("Microsoft.Build.Tasks.V4.0"); CompilerParameters parameters = new CompilerParameters(new string[] { assembly.Location, assembly2.Location, assembly3.Location, assembly4.Location }) { GenerateInMemory = true, TreatWarningsAsErrors = false }; CodeDomProvider provider = CodeDomProvider.CreateProvider("cs"); bool flag = Environment.GetEnvironmentVariable("MSBUILDWRITEXAMLTASK") == "1"; if (flag) { using (StreamWriter writer = new StreamWriter(taskName + "_XamlTask.cs")) { CodeGeneratorOptions options = new CodeGeneratorOptions { BlankLinesBetweenMembers = true, BracingStyle = "C" }; provider.GenerateCodeFromCompileUnit(compileUnit, writer, options); } results = provider.CompileAssemblyFromFile(parameters, new string[] { taskName + "_XamlTask.cs" }); } else { results = provider.CompileAssemblyFromDom(parameters, new CodeCompileUnit[] { compileUnit }); } try { this.taskAssembly = results.CompiledAssembly; } catch (FileNotFoundException) { } if (this.taskAssembly == null) { StringBuilder builder = new StringBuilder(); builder.AppendLine(); foreach (CompilerError error in results.Errors) { if (!error.IsWarning) { if (flag) { builder.AppendLine(string.Format(Thread.CurrentThread.CurrentUICulture, "({0},{1}) {2}", new object[] { error.Line, error.Column, error.ErrorText })); } else { builder.AppendLine(error.ErrorText); } } } helper.LogErrorWithCodeFromResources("Xaml.TaskCreationFailed", new object[] { builder.ToString() }); } return !helper.HasLoggedErrors; }
/// <summary> /// MSBuild engine will call this to initialize the factory. This should initialize the factory enough so that the factory can be asked /// whether or not task names can be created by the factory. /// </summary> public bool Initialize(string taskName, IDictionary<string, TaskPropertyInfo> taskParameters, string taskElementContents, IBuildEngine taskFactoryLoggingHost) { ErrorUtilities.VerifyThrowArgumentNull(taskName, "taskName"); ErrorUtilities.VerifyThrowArgumentNull(taskParameters, "taskParameters"); TaskLoggingHelper log = new TaskLoggingHelper(taskFactoryLoggingHost, taskName); log.TaskResources = AssemblyResources.PrimaryResources; log.HelpKeywordPrefix = "MSBuild."; if (taskElementContents == null) { log.LogErrorWithCodeFromResources("Xaml.MissingTaskBody"); return false; } TaskElementContents = taskElementContents.Trim(); // Attempt to load the task TaskParser parser = new TaskParser(); bool parseSuccessful = parser.Parse(TaskElementContents, taskName); TaskName = parser.GeneratedTaskName; TaskNamespace = parser.Namespace; TaskGenerator generator = new TaskGenerator(parser); CodeCompileUnit dom = generator.GenerateCode(); string pathToMSBuildBinaries = ToolLocationHelper.GetPathToBuildTools(ToolLocationHelper.CurrentToolsVersion); // create the code generator options // Since we are running msbuild 12.0 these had better load. CompilerParameters compilerParameters = new CompilerParameters ( new string[] { "System.dll", Path.Combine(pathToMSBuildBinaries, "Microsoft.Build.Framework.dll"), Path.Combine(pathToMSBuildBinaries, "Microsoft.Build.Utilities.Core.dll"), Path.Combine(pathToMSBuildBinaries, "Microsoft.Build.Tasks.Core.dll") } ); compilerParameters.GenerateInMemory = true; compilerParameters.TreatWarningsAsErrors = false; // create the code provider CodeDomProvider codegenerator = CodeDomProvider.CreateProvider("cs"); CompilerResults results; bool debugXamlTask = Environment.GetEnvironmentVariable("MSBUILDWRITEXAMLTASK") == "1"; if (debugXamlTask) { using (StreamWriter outputWriter = new StreamWriter(taskName + "_XamlTask.cs")) { CodeGeneratorOptions options = new CodeGeneratorOptions(); options.BlankLinesBetweenMembers = true; options.BracingStyle = "C"; codegenerator.GenerateCodeFromCompileUnit(dom, outputWriter, options); } results = codegenerator.CompileAssemblyFromFile(compilerParameters, taskName + "_XamlTask.cs"); } else { results = codegenerator.CompileAssemblyFromDom(compilerParameters, new[] { dom }); } try { _taskAssembly = results.CompiledAssembly; } catch (FileNotFoundException) { // This occurs if there is a failure to compile the assembly. We just pass through because we will take care of the failure below. } if (_taskAssembly == null) { StringBuilder errorList = new StringBuilder(); errorList.AppendLine(); foreach (CompilerError error in results.Errors) { if (error.IsWarning) { continue; } if (debugXamlTask) { errorList.AppendLine(String.Format(Thread.CurrentThread.CurrentUICulture, "({0},{1}) {2}", error.Line, error.Column, error.ErrorText)); } else { errorList.AppendLine(error.ErrorText); } } log.LogErrorWithCodeFromResources("Xaml.TaskCreationFailed", errorList.ToString()); } return !log.HasLoggedErrors; }
/// <summary> /// used for testing. Will load snippets of xml into the task generator /// </summary> /// <param name="s"></param> /// <returns></returns> public static TaskParser LoadAndParse(string s, string desiredRule) { TaskParser tp = new TaskParser(); tp.Parse(s.Replace("`", "\""), desiredRule); return tp; }