Как встроить ресурс в исполняемый файл.NET PE?
Как я могу включить ресурс в.NET PE (Portable Executable) в Visual Studio 2010?
В старые времена мы создавали файл сценария ресурса:
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"
Добавьте этот файл в проект, и компилятор скомпилирует .rc
файл; включая ресурсы в окончательный исполняемый образ.
Что такое управляемый механизм /.NET/Visual Studio для включения ресурсов?
Смотрите также
- MSDN: файлы ресурсов (Visual Studio)
- MSDN: протокол Res
- MSDN: использование ресурсов в MCML
- SO: Что такое res://*/ в.net?
- создание HTML-контента с использованием протокола resx:// и встроенных ресурсов
- Как создать управляемую сборку, содержащую ресурсы Win32, с помощью Visual Studio 2005
Это должны быть стандартные ресурсы; Вы знаете, что каждый может читать как ресурсы:
- Ресурс Хакер будет отображаться как ресурсы
- PEView будет отображаться как ресурсы
- Internet Explorer может читать, используя
res
протокол (например,res://c:\foo\MyProgram.exe/PNG/SplashLogo
)
То, что я пробовал, не работает:
Добавление ресурсов в
Resources.resx
файл:Добавление ресурсов в
Resources.resx
файл и указав действие по сборке Resource:(также попробовал действия Build: Embedded Resource, как мне было предложено в 2008 году)
Обновление: что не сработало
я попытался добавить файл (wumpa.rc
) к проекту:
wumpa.rc:
SplashPNG PNG "Splash.png"
По умолчанию это не сработало. я попытался изменить действие сборки wumpa.rc
:
- Контент (по умолчанию): не работает
- Компиляция: "Пространство имен не может напрямую содержать элементы, такие как поля или методы"
- Встроенный ресурс: не работает
- Ресурс: не работал
Что я получаю (ничего):
Что я ожидаю (что-то):
А затем, когда вы указываете Internet Explorer на ресурс (используя его res
протокол):
res://C:\Develop\Avatar\LocaleInfo\LocaleInfo.exe\PNG\SplashPNG
IE может найти это:
2 ответа
Управляемые ресурсы встраиваются в сборки не так, как ресурсы Win32 - опция "Встроенный ресурс" будет встраивать ваш ресурс в выходную сборку, но не таким образом, чтобы это было доступно с помощью таких вещей, как протокол "res".
Вы можете использовать инструмент для встраивания Win32 в существующий ресурс, как описано здесь: Встраивание ресурсов Win32 в программы на C# (CodeProject).
В качестве альтернативы вы можете использовать /win32res
опция компилятора csc.exe для встраивания скомпилированного .res
ресурс. Этот параметр в настоящее время не предоставляется в качестве опции в Visual Studio 2010, однако здесь приведен ряд инструкций, объясняющих, как это можно сделать. Вам просто нужно скомпилировать свой ресурс как обычно, используя rc.exe
(например, в качестве шага перед сборкой):
<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>
А затем поставьте Win32Resource
свойство для указания выходного файла.res:
<Win32Resource>my_resource_file.res</Win32Resource>
Обновление: в качестве альтернативы вы можете использовать задачу RC MSBuild, если вы не против редактировать MSBuild файл.csproj. Простой пример:
<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>
Это будет работать только если установлен Visual C++.
Вот альтернативное событие предварительной сборки для Visual Studio 2010, которое в меньшей степени зависит от конкретных расположений каталогов:
@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.
Конечно, измените MyResources.rc на соответствующее имя файла.
Если вы используете это событие предварительной сборки, вы можете указать Visual Studio использовать соответствующий файл.RES в диалоговом окне "Свойства проекта" в разделе "Приложение"> "Ресурсы" (для C#).