Build a Project with Resources

If you are going to build localized versions of a project, all user interface elements must be separated into resource files for the different languages. If the project uses only strings, the resource files can simply be text files. Alternatively, the resources can be placed in .resx files.
In this example, the "Hello" project contains two tasks: the Resgen task to compile resources and the Csc task to compile both the source code files and the compiled resources files. In the project file, the two tasks can be placed in the same target or different targets, and these two approaches are compared.

Resgen Task

The library of common tasks that is provided with MSBuild includes a Resgen task that you can use to compile resources in either .resx or text files. This task includes the Sources attribute to specify which resource files to compile and the OutputResources attribute to specify names for the output resource files. If you do not specify the OutputResources attribute in the project file, the Resgen task appends a .resources file extension to the file name of the input files and puts the .resources files in the same directory as the input files.
In this example, the Output element specifies that the OutputResources attribute of the Resgen task (TaskParameter="*OutputResources*") will contain the compiled resource files alpha.resources and beta.resources (*OutputResources*="alpha.resources; beta.resources") and that those two files will be placed inside the Resources item collection (ItemName="Resources"). By identifying those .resources files as a collection of items of the same name, they can then be easily used as inputs for another task, such as Csc.

<Resgen
Sources="alpha.resx; beta.txt"
OutputResources="alpha.resources; beta.resources" >

<Output
TaskParameter="OutputResources"
Type="Resources"/>
</Resgen>

This MSBuild task is equivalent to using the /compile switch for Resgen.exe:

Resgen.exe /compile alpha.resx,alpha.resources /compile beta.txt,beta.resources

Csc Task

Also provided with the library of common tasks is the Csc task, which compiles Visual C# source code files and compiled resources files to produce executables (.exe), dynamic-link libraries (.dll), or code modules (.netmodule). In this example, the Csc task will compile a Visual C# file (Sources="hello.cs") and a collection of compiled resource files that were output from the Resgen task (Resources="@(Resources)"):

<Csc
Sources="hello.cs"
Resources="@(Resources)"
OutputAssembly="hello.exe" />

Using the Resgen and Csc Tasks to Build a Project with Resources

One way of building a project with resources is to place the Resgen and Csc tasks in the same target, for example:

<Target Name="Build">
<Resgen
Sources="alpha.resx; beta.txt"
OutputResources="alpha.resources; beta.resources">
<Output
TaskParameter="OutputResources"
Type="Resources"/>
</Resgen>
<Csc
Sources="hello.cs"
Resources="@(Resources)"
OutputAssembly="hello.exe"/>
</Target>

Using this approach, the project builds as required, but the target is becoming large and inflexible. If you later wanted to add other tasks to run between Resgen and Csc, putting them all in one target would make the project file very difficult to read. Also, authoring such large targets with so many tasks makes it difficult to perform good incremental builds — builds in which only those targets that have not been built before or targets that are out of date are rebuilt.
A better way of authoring a project file is to use multiple targets and explicitly express dependencies between them. This approach also gives you the ability to run any of the targets separately and perform a smaller set of tasks rather than running a long list of tasks in one target every time you build. In this example, each task is in a separate target and the DependsOnTargets attribute specifies that the Resources target must run before the Build target can run (Target Name="Build" *DependsOnTargets*="Resources"):

<Target Name="Resources">
<Resgen
Sources="alpha.resx; beta.txt"
OutputResources="alpha.resources; beta.resources" >
<Output
TaskParameter="OutputResources"
Include=" "
Type="Resources"/>
</Resgen>
</Target>

<Target Name="Build" DependsOnTargets="Resources">
<Csc
Sources="hello.cs"
Resources="@(Resources)"
OutputAssembly="hello.exe"/>
</Target>

A target can depend on one or more other targets. To specify more than one target, use a semicolon to separate the list of targets.

Project Files

Visual C# example

Download code

<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets = "Build">

<Target Name="Resources">
<Resgen
Sources="alpha.resx; beta.txt"
OutputResources="alpha.resources; beta.resources">
<Output
TaskParameter="OutputResources"
ItemName="Resources"/>
</Resgen>
</Target>

<Target Name="Build" DependsOnTargets="Resources">
<Csc
Sources="hello.cs"
Resources="@(Resources)"
OutputAssembly="hello.exe"/>
</Target>

</Project>
Microsoft Communities