Search code examples
c#msbuildmsbuild-task

Custom task MSBuild


I created a .dll file that parses WSDL me file and saves it to other files. File is called WsdlParser.dll. Input parameters are: the input file , output file ,the element and parent element. I need to build at another program to call this my dll and enter the data for MSBuild(I need to build at another program to create those files from WSDL).Method parser me to create new files. I have created a project where I put reference Microsoft.Build.Framework , Microsoft.Build.Utulities , WsdlParser.

  namespace MyParserBuild
{
    public class ParserClass : Task
    {
        private string input;
        private string output;
        private string element;
        private string parentElement;

        public override bool Execute()
        {
            try
            {
                WsdlParser.Parser parse = new WsdlParser.Parser(input, output);
                parse.Parse(parentElement, element);
            }

            catch (Exception e)
            {
                Console.WriteLine(e);
                return false;
            }
            return true;
        }

        /*  Properties  */
        [Required]
        public string Input
        {
            get { return input; }
            set { input = value; }
        }

        [Required]
        public string Output
        {
            get { return output; }
            set { output = value; }
        }

        [Required]
        public string Element
        {
            get { return element; }
            set { element = value; }
        }

        [Required]
        public string ParentElement
        {
            get { return parentElement; }
            set { parentElement = value; }
        }
    }
}

And I create an XML file named MyBuild.targets

    <?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask TaskName="MyParserBuild.ParserClass" AssemblyFile="C:\Work\Common code\MyCode\MyParserBuild\MyParserBuild\bin\Debug\MyParserBuild.dll"/>

  <!--Variable-->
  <PropertyGroup>
    <PG_Input>C:\Work\Common code\MyCode\MyParserBuild\MyParserBuild\MyWSDLFile2.wsdl</PG_Input>
    <PG_Output>C:\Users\Administrator\Desktop\test</PG_Output>
    <PG_Element>schema</PG_Element>
    <PG_ParentElement>types</PG_ParentElement>
  </PropertyGroup>

  <Target Name="PreBuild">
    <ParserClass Input="$(PG_Input)"
                 Output="$(PG_Output)"
                 Element="$(PG_Element)"
                 ParentElement="$(PG_ParentElement)" />
  </Target>
</Project>

Finally, I put this target into .csproj another program.

<Import Project="C:\Work\Common code\MyCode\MyParserBuild\MyParserBuild\MyBuild.targets"/>

My problem is that when I build another program will not create those files from WSDL.


Solution

  • You only imported the project, but you did not add anything which will make the target get called: it's not because the target is named 'PreBuild' that it will be used as pre build event. To do that there are a couple of options, here are two of them:

    1. Modify the project file to call the PreBuild Target, for instance add this et the end of the file:

      <Target Name="BeforeBuild" DependsOnTargets="PreBuild">
      </Target>
      
    2. Use a PreBuildEvent call the target PreBuild. A pre build event is something which runs like on the commandline. In Visual Studio, right-click the project, select Properties and then Build Events. Enter

      msbuild MyBuild.targets /t:PreBuild
      

      In this case you do not need to import the MyBuild.targets in your project.

    Note: it is not a good idea to use absolute paths like C:\Work\Common code\MyCode\.... If you'd copy your code to another location everything would break. better figure out a directory structure you'll stick with and use relative paths within that structure, or make everything parameterized like $(CommonCodePath)\MyBuild.targets and pass CommonCodePath as a property to msbuild or so.