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; }
public void TestGenerateToFile() { string xml = @"<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=`CL`> <EnumProperty Name=`GeneratePreprocessedFile` Switch=`nologo`> <EnumValue Name=`Disabled` /> <EnumValue Name=`Yes` Switch=`P` /> <EnumValue Name=`NoLineNumbers` Switch=`EP` /> </EnumProperty> </Rule> </ProjectSchemaDefinitions>"; TaskParser tp = XamlTestHelpers.LoadAndParse(xml, "CL"); TaskGenerator tg = new TaskGenerator(tp); CodeCompileUnit compileUnit = tg.GenerateCode(); CodeDomProvider codeGenerator = CodeDomProvider.CreateProvider("CSharp"); try { using (StreamWriter sw = new StreamWriter("XamlTaskFactory_Tests_TestGenerateToFile.cs")) { CodeGeneratorOptions options = new CodeGeneratorOptions(); options.BlankLinesBetweenMembers = true; options.BracingStyle = "C"; codeGenerator.GenerateCodeFromCompileUnit(compileUnit, sw, options); } CSharpCodeProvider provider = new CSharpCodeProvider(); // Build the parameters for source compilation. CompilerParameters cp = new CompilerParameters(); // Add an assembly reference. cp.ReferencedAssemblies.Add("System.dll"); cp.ReferencedAssemblies.Add("System.XML.dll"); cp.ReferencedAssemblies.Add(Path.Combine(XamlTestHelpers.PathToMSBuildBinaries, "microsoft.build.utilities.core.dll")); cp.ReferencedAssemblies.Add(Path.Combine(XamlTestHelpers.PathToMSBuildBinaries, "microsoft.build.tasks.core.dll")); cp.ReferencedAssemblies.Add(Path.Combine(XamlTestHelpers.PathToMSBuildBinaries, "microsoft.build.framework.dll")); cp.ReferencedAssemblies.Add("System.Data.dll"); // Generate an executable instead of // a class library. cp.GenerateExecutable = false; // Set the assembly file name to generate. cp.GenerateInMemory = true; // Invoke compilation CompilerResults cr = provider.CompileAssemblyFromFile(cp, "XamlTaskFactory_Tests_TestGenerateToFile.cs"); Assert.Equal(0, cr.Errors.Count); // "Compilation Failed" } finally { if (File.Exists("XamlTaskFactory_Tests_TestGenerateToFile.cs")) { File.Delete("XamlTaskFactory_Tests_TestGenerateToFile.cs"); } } }
/// <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; }
public static Assembly SetupGeneratedCode(string xml) { TaskParser tp = null; try { tp = LoadAndParse(xml, "FakeTask"); } catch (XamlParseException) { Assert.True(false, "Parse of FakeTask XML failed"); } TaskGenerator tg = new TaskGenerator(tp); CodeCompileUnit compileUnit = tg.GenerateCode(); CodeDomProvider codeGenerator = CodeDomProvider.CreateProvider("CSharp"); using (StringWriter sw = new StringWriter(CultureInfo.CurrentCulture)) { CodeGeneratorOptions options = new CodeGeneratorOptions(); options.BlankLinesBetweenMembers = true; options.BracingStyle = "C"; codeGenerator.GenerateCodeFromCompileUnit(compileUnit, sw, options); CSharpCodeProvider provider = new CSharpCodeProvider(); // Build the parameters for source compilation. CompilerParameters cp = new CompilerParameters(); // Add an assembly reference. cp.ReferencedAssemblies.Add("System.dll"); cp.ReferencedAssemblies.Add("System.Data.dll"); cp.ReferencedAssemblies.Add("System.XML.dll"); cp.ReferencedAssemblies.Add(Path.Combine(PathToMSBuildBinaries, "Microsoft.Build.Framework.dll")); cp.ReferencedAssemblies.Add(Path.Combine(PathToMSBuildBinaries, "Microsoft.Build.Utilities.Core.dll")); cp.ReferencedAssemblies.Add(Path.Combine(PathToMSBuildBinaries, "Microsoft.Build.Tasks.Core.dll")); // Generate an executable instead of // a class library. cp.GenerateExecutable = false; // Set the assembly file name to generate. cp.GenerateInMemory = true; // Invoke compilation CompilerResults cr = provider.CompileAssemblyFromSource(cp, sw.ToString()); foreach (CompilerError error in cr.Errors) { Console.WriteLine(error.ToString()); } if (cr.Errors.Count > 0) { Console.WriteLine(sw.ToString()); } Assert.Equal(0, cr.Errors.Count); if (cr.Errors.Count > 0) { foreach (CompilerError error in cr.Errors) { Console.WriteLine(error.ErrorText); } } return cr.CompiledAssembly; } }