如何在.NET PE可执行文件中嵌入资源?
如何在Visual Studio 2010的.NET PE(可移植可执行文件)中包含资源 在中,我们将创建一个资源脚本文件: wumpa.rc:如何在.NET PE可执行文件中嵌入资源?,.net,visual-studio,visual-studio-2010,resources,.net,Visual Studio,Visual Studio 2010,Resources,如何在Visual Studio 2010的.NET PE(可移植可执行文件)中包含资源 在中,我们将创建一个资源脚本文件: wumpa.rc: jqueryjs RCDATA "jquery.js" SplashLogo PNG "Hello world.png" ReportLogo RCDATA "ReportLogo.png" Users ICON "User XP.ico" Toolbar
jqueryjs RCDATA "jquery.js"
SplashLogo PNG "Hello world.png"
ReportLogo RCDATA "ReportLogo.png"
Users ICON "User XP.ico"
Toolbar BITMAP "StandardToolbar24_32bpp.bmp"
将该文件添加到项目中,编译器将编译.rc
文件;包括最终可执行映像中的资源
包含资源的managed/.NET/visualstudio机制是什么
另见
- MSDN:
- MSDN:
- MSDN:
- 因此:
这些必须是标准资源;您知道每个人都可以阅读的资源:
- 资源黑客将显示为资源
- PEView将显示为资源
- Internet Explorer可以使用进行读取(例如
)res://c:\foo\MyProgram.exe/PNG/SplashLogo
我尝试过的不起作用的事情:
resources.resx
文件:
resources.resx
文件,并指定资源的生成操作:
SplashPNG PNG "Splash.png"
(还尝试了构建操作:嵌入式资源,如图所示)更新:什么不起作用 我尝试将文件(
wumpa.rc
)添加到项目中:
wumpa.rc:
SplashPNG PNG "Splash.png"
默认情况下,它不起作用。我尝试更改wumpa.rc
的构建操作:
- 内容(默认设置):不起作用
- 编译:“命名空间不能直接包含字段或方法等成员”
- 嵌入式资源:无法工作
- 资源:不起作用
res
协议):
IE可以找到它:
托管资源以与Win32资源不同的方式嵌入程序集-“嵌入资源”选项将将您的资源嵌入到输出程序集中,但是 不是以一种使用“res”协议之类的东西可以访问的方式 您可以使用工具将Win32嵌入现有资源,如下所述: 或者,您可以使用
/win32res
csc.exe编译器选项嵌入已编译的.res
资源。此选项当前未作为Visual Studio 2010中的选项公开,但是有一系列说明说明了如何执行此操作。您只需使用rc.exe
(例如,作为预构建步骤)正常编译资源即可:
更新:也可以使用,只要您不介意编辑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>
@(ResourceCompile->'%(RelativeDir)%(filename).res')
<>这将仅在VisualC++安装时工作。 < P>这里是VisualStudio 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在“应用程序>资源”(对于C#)下的“项目属性”对话框中使用相应的.RES文件。阻抗不匹配非常大,托管资源的工作方式非常不同。您仍然可以使用project+属性、应用程序选项卡和资源文件将.res文件添加到项目中。你读这些书不会得到任何帮助。因此,我不能在我的解决方案中添加一个<代码> .RC < /C>文件,并让VisualStudio的资源编译器编译它吗?当然,你可以添加一个C++项目。“你似乎对阅读参考资料的困难太不放心了。”汉帕桑很幸运,它们并不都适合我。有些是用于Internet Explorer等需要资源映像的程序(即,不能将映像提供给
WebBrowser
控件或其本机IWebBrowser
COM对象)。但是我对添加res
文件不感兴趣,因为这需要一个编译器。我使用了一个开发工具,在这个工具中,您可以像添加.cs
文件一样轻松地将.rc
文件添加到解决方案中,并且编译器/链接器可以处理它。是的,您有一个,Visual Studio。还没有尝试过C++项目吗?他正在使用资源黑客在构建EXE之后手动添加资源。当你有几十种资源时,这不是一个真正的解决方案,并且在添加可执行文件之前无法运行这些文件。@IanBoyd我已经更新了我的答案,添加了一些关于如何使用csc/win32res
选项来执行此操作的提示-恐怕我以前从未这样做过,所以我不知道执行此操作的最佳方法,但希望此答案能给您一些提示。请在回答之前附上“虽然Visual Studio的未来版本可能支持它,但Visual Studio 2010不支持在.NET可移植可执行文件中编译资源。”我接受它。这似乎是正确的答案(即,您不能)@IanBoyd找到了一篇更好的文章,解释了如何使用预构建步骤来实现这一点。问题是我与其他开发人员一起工作。我不能修改硬代码路径的解决方案,这将在其他开发人员的机器上失败。
<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>
@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.