I would like to define a custom build step to generate C# source code files from a C# interface. The generated files are to be part of another assembly in the same solution. I want the generation to take place whenever the cs file containing the interface has changed.
In VC++ it is possible to define a custom build step, with dependencies, in the source file properties page. Not so in VC#. (Using a project pre-build step would mean that the files are generated on every build.)
I assume there is some way to do this with MSBuild but I'm having trouble finding information on how.
Can anyone point into the documentation for me

Custom build step for C# files ?
Pramod_SN
This is entertaining :) There's two things you need to do:
Here's a stub of what the XML would look like:
<
Target Name="BeforeBuild" Inputs="@(InterfaceFiles)" Outputs="@(InterfaceFiles->'%(Identity).cs')"><GenerateInterfaceFiles Interfaces="@(InterfaceFiles)">
<Output TaskParameter="GeneratedSourceFiles" ItemName="Compile"/>
</GenerateInterfaceFiles>
</Target>
There's a lot going on here so let me explain. This snippet overrides the default BeforeBuild target to ensure your custom task runs before the build. See our blog entry on the subject for more information on how this works.
The Inputs and Outputs tags tell MSBuild the information it needs to perform up-to-date cheques. The InterfaceFiles item group is the list of inputs to the custom task. The Outputs is a transformation that explains the 1-1 mapping of the interface files to the generated .cs files. This solves point #1 above.
The "GenerateInterfaceFiles" XML is the name I made up for your custom task. It takes in a list of source files that are defined in the item group called InterfaceFiles. It returns a list of the generated files via the GeneratedSourceFiles and adds it to the pre-defined ItemList called "Compile", which is the list of source files that will get compiled by the build process. This solves point #2 above.
It is very important to note that this will only work if there is exactly one interface per file, and if your task generates exactly one .cs file for each input file. Further, you have to know at XML authoring time (not at task execution time) how the names of inputs to outputs will map. I am assuming your files are something like this:
interface1.ifl
interface2.ifl
interface2.ifl
where ifl is some dorky extension I came up with. This will result in the following generated files:
interface1.cs
interface2.cs
interface3.cs
If this 1-1 mapping isn't true, then you won't be able to get the up-to-date checks you want.
I hope this helps, and more importantly I hope it makes sense :) Your little question touched on some of the hardest parts of MSBuild: transformations and output properties.
Neil
thedrs
Yes, that's how you'd specify the InterfaceFiles item group.
GenerateInterfaceFiles isn't a command-line; it's a call to the cusotm task you'd write to do the conversion from interface file to source code implementation. Faisal has a series up on our blog (http://blogs.msdn.com/msbuild) on how to write custom tasks if you need more information, including how you'd pass back the list of generated files.
There's no way to get around the 1-1 mapping if you want to have up-to-date checks by the build engine. If you leave off the inputs and outputs tags then you'd have to build up-to-date check logic into your custom task rather than having the engine do it.
The output syntax is kind of confusing. It basically is a transformation that changes the file extension of each file in the InterfaceFiles group to a different file extension. If you want to completely change the file name then you'd have to get fancier and likely apply metadata to each of the InterfaceFiles items that indicates what the generated file name will be, then use that metadata in the output transform instead.
You can specify a custom build step that only invokes a command line command using the Pre and Post-Build steps in the project properties page for a C# or VB application, but it is quite limited. For what you're after you are likely better off editing the project file as we've been discussing in this thread.
Neil
Srikar
Thanks for your answer, but I still have some questions...
How do I specifiy the InterfaceFiles item group Like this
<ItemGroup>
<InterfaceFiles Include="..\Foo\IFoo.cs">
</ItemGroup>
Is <GenerateInterfaceFiles Interfaces="@(InterfaceFiles)"> a command line Can I supply program arguments there What's the syntax
How do I set the GeneratedSourceFiles from my generator program
Is there no way to get around the 1-1 mapping requirement I want to have more than one output file but only one input file.
What does the Outputs syntax mean Map ..\Foo\IFoo.cs to IFoo.cs in my example I want to specify other names for the output files, can I just type "..\Foo\IFoo.cs->Fie.cs" instead
How come it's not possible to specify custom build steps for C# projects in VS project properties like for C++