.NET 应用程序中的嵌入式资源存储在哪里?
如果我将资源添加到 Resources.resx,它们是否嵌入到可执行文件中?
我在某处读到资源存储在程序集中,但是项目中的所有文件(包括输出文件夹中的文件)都是程序集的一部分吗?
或者,程序集是否只是编译器生成的文件和模块,程序集中不包含资源?
有人可以确切地说明这是如何工作的吗?
If I add resources to Resources.resx, are they are embedded within the executable?
I have read somewhere that resources are stored within the assembly, but are all files in the project (including files in the output folder) part of the assembly?
Or, is the assembly just files and modules produced by compiler and resources aren't included in the assembly?
Can somebody clarify exactly how this works?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
快速回答
您添加到 C# 程序的资源存储在 PE 的资源部分中
二进制。
例如,如果我添加一个字符串
MyTestString
,其值为"Charles is Cool"
如果我在十六进制编辑器中打开编译后的二进制文件,我可以查看我的字符串:
很酷,但是它是怎么到这里的呢?
C# 端
资源编辑器生成 Resources.Designer.cs,这是它生成的内容
但是等等...我在这里没有看到
“Charles is Cool”
...它去了哪里?GetString()
从哪里获取它?好吧,最终它对资源卑躬屈膝(MSFT的术语,而不是我的),我想我们应该将其视为
ManifestBasedResourceGroveler
,它最终会让我们extern GetResource()
,肯定的这表明我们已经脱离了 .NET 宇宙的边缘...您知道这意味着...CoreCLR 方面
我们可以查看 coreclr 存储库以获取如何实现它的示例,
如果您要跟踪在这里编写代码你最终会到达
PEDecoder::GetResource()
基本上找到了 PE 头的偏移量(参见
IMAGE_COR20_HEADER
) 。查看 Wikipedia 上的可移植可执行文件,您将看到 svg 图像有一个 ResourceTable 部分(RVA,又名 相对虚拟地址)我在这里得到的是,资源不是'无论如何,它们不是 C# 或 .NET 功能,它们只是 PE 二进制格式始终具有的托管 API。
对于任意二进制资源
请注意,我所说的所有内容都适用于任意数据,如果您要向资源中添加一些二进制文件,
Resources
会将其作为byte[]
呈现给您> 但实际上它会将其编码为其他东西。虽然在 Visual Studio 中打开 resx 文件会为您提供导入的二进制文件的相当无趣的路径,但请注意,如果您以 JetBrains DotPeek 并查看 resx 文件,该文件的路径已被替换为字符串,
而我无法在 Visual Studio 端找到任何代码来证明它,我会猜测该字符串是(二进制)资源文件中字节的 Base64 编码版本,因为运行
Convert.ToBase64String(Resources.binary)
给出的字符串与编译的二进制文件的 resx 文件中找到的字符串相同。对于那些想在家尝试的人,我的二进制文件仅包含08 67 53 09 BE EF CA FE C0 0F FE AB CD EF
。The quick answer
The resources you add to a C# program are stored in the resources section of the PE
binary.
For example, if I add a string,
MyTestString
, with the value"Charles is Cool"
If I open up the compiled binary in a hex editor, I can see my string:
Cool, but how did it get here?
The C# side
The resource editor generates Resources.Designer.cs, here's what it generated
But wait... I don't see
"Charles is Cool"
anywhere in here... where did it go? Where isGetString()
getting it from?Well eventually it grovels for the resource (MSFT's terminology, not mine), I suppose we should consider this a
ManifestBasedResourceGroveler
, which eventually gets us toextern GetResource()
, a sure sign that we've fallen off the edge of the .NET universe... you know that that means...The CoreCLR Side
We can look at the coreclr repository for an example of how this is implemented,
If you were to trace the code here you eventually come to
PEDecoder::GetResource()
Which basically finds the offset from the PE header (see
IMAGE_COR20_HEADER
). Check out the Portable Executable article on Wikipedia, you will see that the svg image has a section for ResourceTable (RVA, aka Relative Virtual Address)What I'm getting at here is, Resources aren't by any means a C# or .NET feature, they're just a managed API into something the PE binary format always had.
For arbitrary binary resources
Note that everything I said works for arbitrary data, if you were to add some binary file to your resources,
Resources
would present it to you as abyte[]
but really it would encode it as something else.While opening up the resx file in Visual Studio gives you a rather uninteresting path to the binary file that you imported, note that if you open up the compiled binary in something like JetBrains DotPeek and look at the resx file, the path to the file has been replaced with a string,
While I was not able to find any code on the Visual Studio side to prove it, I would guess this string is a base64 encoded version of the bytes in the (binary) resource file because running
Convert.ToBase64String(Resources.binary)
gives me the same string that's found in the compiled binary's resx file. For those of you who want to try this at home my binary file just contained08 67 53 09 BE EF CA FE C0 0F FE AB CD EF
.嵌入式资源存储在 DLL 或 EXE 文件内。
The embedded resources are stored inside the DLL or EXE files.