如何更改为嵌入式资源生成的 ManifestResourceName

How to change the generated ManifestResourceName for Embedded Resources

在 C# 项目中,为 Embedded Resource 生成的资源名称在默认情况下会经过一些修饰,使生成的名称成为命名空间的有效语言标识符。

例如 Foo/Bar/123.txt 变为 {Default Namespace}.Foo.Bar._123.txt 并且我必须用 asm.GetManifestResourceStream("Yuck.Foo.Bar._123.txt") 加载它。

我宁愿让我的资源保留它们的相对路径,例如 Foo/Bar/123.txt 以更好地模拟虚拟文件系统,这样我就可以加载它们,例如 asm.GetManifestResourceStream("Foo/Bar/123.txt").

现在知道.Net没有对资源名称做限制,看来是可行的。

但是如何让构建引擎为我生成合理的路径名?

.csproj 文件中,Embedded Resources 被定义为 <EmbeddedResource> 项。

这些具有名为 <LogicalName> 的元数据,它允许覆盖资源的名称,否则将生成任何名称。

例如:

<ItemGroup>
  <EmbeddedResource Include="Foo\Bar3.txt">
    <LogicalName>Foo\Bar3.txt</LogicalName>
  </EmbeddedResource>
</ItemGroup>

将生成可以使用 asm.GetManifestResourceStream("Foo\Bar3.txt")

加载的资源

要为我们所有的嵌入式资源执行此操作,我们可以将重命名任务添加到 .csproj 文件,该文件在生成默认名称之前运行并明确分配我们选择的名称:

<Target Name="ModifyEmbeddedResourceNames" BeforeTargets="CreateManifestResourceNames">
  <ItemGroup>
    <EmbeddedResource>
      <LogicalName>%(EmbeddedResource.Identity)</LogicalName>
    </EmbeddedResource>
  </ItemGroup>
</Target>

有了这个,我们得到了以 Identity.

命名的资源

如果您使用的是“新式”(也称为“SDK 式”).csproj 文件,那么您可以利用 of new behaviour in MSBuild that allows properties on MSBuild Items to be specified as attributes instead of as child elements.

所以不要这样做:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <!-- etc -- >

  <ItemGroup>
    <EmbeddedResource Include="Foo/Bar/123.txt">
      <LogicalName>FooBar123Txt</LogicalName>
    </EmbeddedResource>
  </ItemGroup>

</Project>

您现在可以这样做:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <!-- etc -- >

  <ItemGroup>
    <EmbeddedResource Include="Foo/Bar/123.txt" LogicalName="FooBar123Txt" />
  </ItemGroup>

</Project>