How can i include a resource in a .NET PE (Portable Executable) in Visual Studio 2010?
In the olden days we would create a resource script file:
wumpa.rc:
jqueryjs RCDATA "jquery.js"
SplashLogo PNG "Hello world.png"
ReportLogo RCDATA "ReportLogo.png"
Users ICON "User XP.ico"
Toolbar BITMAP "StandardToolbar24_32bpp.bmp"
Add that file to the project, and the compiler would compile the .rc
file; including resources in the final executable image.
What is the managed/.NET/Visual Studio mechanism to include resources?
These have to be standard resources; you know the kind that everyone can read as resources:
res
protocol (e.g. res://c:\foo\MyProgram.exe/PNG/SplashLogo
)Things i've tried that don't work:
Adding resources to the Resources.resx
file:
Adding resources to the Resources.resx
file, and specifying a build action of Resource:
(also tried Build actions: Embedded Resource, as was suggested to me in 2008)
Update: What didn't work
i tried adding a file (wumpa.rc
) to the project:
wumpa.rc:
SplashPNG PNG "Splash.png"
By default it didn't work. i tried changing the Build Action of wumpa.rc
:
What i get (nothing):
What i expect (something):
And then when you point Internet Explorer at the resource (using its res
protocol):
res://C:\Develop\Avatar\LocaleInfo\LocaleInfo.exe\PNG\SplashPNG
IE can find it:
Managed resources are embedded into assemblies in a different way from Win32 resources - the "Embedded resource" option will embed your resource into the output assembly, but not in a way that is accessible using things like the "res" protocol.
You can either use a tool to embed a Win32 into an existing resource as described here: Embed Win32 resources in C# programs (CodeProject).
Alternatively you can use the /win32res
csc.exe compiler option to embed a compiled .res
resource. This option is not currently exposed as an option in Visual Studio 2010 however there is a series of instructions here that explains how you can do this. You simply need to compile your resource as normal using rc.exe
(e.g. as a pre-build step):
<Target Name="BeforeBuild" Inputs="my_resource_file.rc" Outputs="my_resource_file.res">
<Exec Command=""C:\Program Files\Microsoft Visual Studio 8\VC\bin\rc.exe" /r my_resource_file.rc" />
</Target>
And then supply the Win32Resource
property to specify the output .res file:
<Win32Resource>my_resource_file.res</Win32Resource>
Update: As an alternative you can use the RC MSBuild task as long as you don't mind editing MSBuild your .csproj file. A simple example:
<UsingTask TaskName="RC" AssemblyName="Microsoft.Build.CppTasks.Common, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
<PropertyGroup>
<Win32Resource Condition="'$(Win32Resource)' != ''">@(ResourceCompile->'%(RelativeDir)%(filename).res')</Win32Resource>
</PropertyGroup>
<ItemGroup>
<ResourceCompile Include="test.rc" />
</ItemGroup>
<Target Name="ResourceCompile" BeforeTargets="BeforeCompile" Condition="'@(ResourceCompile)' != ''">
<RC Source="@(ResourceCompile)" />
</Target>
This will only work if Visual C++ is installed.
Here is an alternative pre-build event for Visual Studio 2010 that is less dependent on specific directory locations:
@echo.
set RCDIR=
IF EXIST "$(FrameworkSDKDir)Bin\rc.exe" (set RCDIR="$(FrameworkSDKDir)Bin\rc.exe")
IF EXIST "$(DevEnvDir)..\..\VC\Bin\rc.exe" (set RCDIR="$(DevEnvDir)..\..\VC\Bin\rc.exe")
IF EXIST "$(DevEnvDir)..\..\SDK\v2.0\Bin\rc.exe" (set RCDIR="$(DevEnvDir)..\..\SDK\v2.0\Bin\rc.exe")
IF EXIST "$(DevEnvDir)..\..\SDK\v3.5\Bin\rc.exe" (set RCDIR="$(DevEnvDir)..\..\SDK\v3.5\Bin\rc.exe")
IF EXIST "$(DevEnvDir)..\..\..\Microsoft SDKs\Windows\v6.0a\bin\rc.exe" (set RCDIR="$(DevEnvDir)..\..\..\Microsoft SDKs\Windows\v6.0a\bin\rc.exe")
IF EXIST "$(DevEnvDir)..\..\..\Microsoft SDKs\Windows\v7.0a\bin\rc.exe" (set RCDIR="$(DevEnvDir)..\..\..\Microsoft SDKs\Windows\v7.0a\bin\rc.exe")
if not defined RCDIR (echo "Error! Unable to find rc.exe.") ELSE (%RCDIR% /r "$(ProjectDir)MyResources.rc")
if not defined RCDIR (Exit 1)
@echo.
Of course, change MyResources.rc to the appropriate file name.
If you use this pre-build event, you can tell Visual Studio to use the corresponding .RES file in the Project Properties dialog under Application > Resources (for C#).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With