How to build a managed assembly that contains Win32 resources using Visual Studio 2005

A few weeks ago, I started working on a sample Media Center add-in using the test builds of the February CTP version of the Media Center SDK. During this process, I needed to figure out how to create a project in Visual Studio 2005 that could build Win32 resources and include them as part of a managed assembly.

I struggled for a while as I looked through the documentation for Visual Studio 2005 and tried different scenarios. Eventaully I asked a friend of mine who works on the MSBuild team and his advice along with a little further experimentation got me to a working solution. Since I struggled for a while with this scenario, I decided to document it here as well in the hopes that it will save some effort on the part of anyone who searches for help about this topic later on.

Here are the steps I followed to add Win32 resources to a managed assembly in Visual Studio 2005.

1. Create a .RC file to represent the resources

If you know the syntax, you can create a .RC file directly in a text editor such as notepad. You can also use Visual C++ and choose Add Resources to create a .RC file, or you can use an example from another application you have already created and modify it in notepad.

2. Compile the .RC file into a .RES file

You can use resource compiler tool (named rc.exe) that is available in %ProgramFiles%\Microsoft Visual Studio 8\VC\Bin if you have Visual Studio 2005 installed to the default location. The command line is rc.exe /r <path to the .RC file>. This will create a .RES file with the same name as the .RC file in the same location as the .RC file.

You can also configure your .csproj file to automatically compile the .RC file into a .RES file as a pre-build task. In order to accomplish this, open the .csproj file in a text editor such as notepad, uncomment the section at the bottom of the .csproj file that includes the BeforeBuild target and author a target similar to the following as a BeforeBuild step:

<Target Name="BeforeBuild" Inputs="my_resource_file.rc" Outputs="my_resource_file.res">
<Exec Command="&quot;C:\Program Files\Microsoft Visual Studio 8\VC\bin\rc.exe&quot; /r my_resource_file.rc" />
</Target>

Note that this command line assumes that you have Visual Studio 2005 installed to the default location on your system. You may need to adjust the command line as appropriate based on where rc.exe exists on your system.

If you decide to manually edit your .csproj file, I suggest making a backup copy in case you run into syntax errors and need to revert to a known-good copy and start over.

3. Build your managed assembly with a reference to the .RES file included

You can associate a .RES file to a Visual C# project in Visual Studio 2005 by right-clicking on the project in the Solution Explorer, choosing the Application tab, clicking the Resource File radio button and then specifying the .RES file in the text box. The .RES file must already exist in order to specify it in the Visual Studio UI.

Alternatively, you can open your .csproj file in a text editor such as notepad and add the following line to the <PropertyGroup> section at the top of the file:

<Win32Resource>my_resource_file.res</Win32Resource>

Visual Studio will pass the file listed in the <Win32Resource> tag to the C# compiler (csc.exe) using the /win32res:<file> command line parameter if it finds that tag in your .csproj file.

Media Center-specific side notes if you're interested:

  • The February CTP version of Media Center supports loading resources using the Win32 res:// protocol but not the managed code resx:// protocol, which is why I needed to figure out this scenario in the first place
  • If you have the February CTP version of the Media Center SDK, you can look at the project located at %ProgramFiles%\Microsoft SDKs\Windows Media Center\v5.0\Samples\Mcml Samples\HelloMcml for a live, working example of the technique described above. I used the steps listed above when I created that sample.