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");
                }
            }
        }
Example #3
0
        /// <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;
        }
Example #4
0
        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;
            }
        }