如何防止嵌入式资源的资源汇编生成

3
我有一个项目,在其中嵌入了一些文件,其中两个文件以 .SMS.something 结尾。当项目被编译时,即使我没有指定要使用分离的程序集,也会生成一个“SMS”文化的卫星程序集,这到底是什么文化呢?
我已经四处搜寻解释,但是还是摸不着头脑。我找到的唯一信息就是人们试图将实际的文化资源程序集嵌入到可执行文件中,但这不是我的情况。我只想要所有嵌入的资源都在同一个程序集中,且只有一种语言。
我该如何避免自动生成卫星程序集,或指定 SMS 不是一种文化?

构建系统无法从项目中明确获取到 .resx 文件需要转换为卫星程序集的线索,除了文件名格式。您使用文件名中的句点会使该逻辑出现问题。请选择一个名称,任何名称,只要不是类似于可本地化的 .resx 文件即可。 - Hans Passant
文件名不以.resx结尾,必须包含句点。我目前正在尝试覆盖构建过程中的一些内容来取得进展。如果我找到了可行的解决方案,我将发布一个答案。 - Sense545
1个回答

5

我通过查看Microsoft.Common.targets和Microsoft.CSharp.targets文件,找出了用于对资源进行排序并为其命名的任务,从而以一种非常hacky但完美运行的方式解决了这个问题。

因此,我覆盖了CreateCSharpManifestResourceName任务,并设置了ManifestResourceName和LogicalName等内容,使其符合我的要求:

<!-- Overriding this task in order to set ManifestResourceName and LogicalName -->
<UsingTask TaskName="CreateCSharpManifestResourceName" TaskFactory="CodeTaskFactory"
           AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
  <ParameterGroup>
    <ResourceFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]"
                   Required="true" />
    <RootNamespace ParameterType="System.String"
                   Required="true" />
    <PrependCultureAsDirectory
                   ParameterType="System.Boolean" />
    <ResourceFilesWithManifestResourceNames
                   ParameterType="Microsoft.Build.Framework.ITaskItem[]"
                   Output="true" />
  </ParameterGroup>
  <Task>
    <Code Type="Fragment" Language="cs">
      foreach (ITaskItem item in ResourceFiles) {
        var link = item.GetMetadata("Link").Replace("\\", "/");
        link = "/" + link.TrimStart('/');
        item.SetMetadata("ManifestResourceName", link);
        item.SetMetadata("LogicalName", link);
      }
      ResourceFilesWithManifestResourceNames = ResourceFiles;
    </Code>
  </Task>
</UsingTask>

作为额外的好处,我嵌入的文件会以它们的实际路径作为资源名称(只用\替换成/),因此可以轻松使用Assembly.GetManifestResourceStream(x)查找它们,其中x可能是/path.to/my.SMS.file之类的内容。
然后,我用一个覆盖AssignCulture任务的函数代替了原来的任务,并返回没有任何文件具有任何语言环境,并且将<WithCulture>false</WithCulture>添加到这些文件中(这在我的情况下非常完美)。
<!-- Overriding this task to set WithCulture and sort them as not having culture -->
<UsingTask TaskName="AssignCulture" TaskFactory="CodeTaskFactory"
           AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
  <ParameterGroup>
    <Files ParameterType="Microsoft.Build.Framework.ITaskItem[]"
           Required="true" />
    <AssignedFilesWithCulture
           ParameterType="Microsoft.Build.Framework.ITaskItem[]"
           Output="true" />
    <AssignedFilesWithNoCulture
           ParameterType="Microsoft.Build.Framework.ITaskItem[]"
           Output="true" />
    </ParameterGroup>
    <Task>
        <Code Type="Fragment" Language="cs">
            ITaskItem[] withCulture = new ITaskItem[Files.Length];
            ITaskItem[] withoutCulture = new ITaskItem[Files.Length];
            for (var i = 0; i &lt; Files.Length; i++) {
                ITaskItem item = Files[i];
                var wc = item.GetMetadata("WithCulture");
                if (wc == "") { item.SetMetadata("WithCulture", "False"); }
                if (wc.ToLowerInvariant() == "true") {
                    withCulture[i] = item;
                } else {
                    withoutCulture[i] = item;
                }
                var type = item.GetMetadata("Type");
                if (type == "") { item.SetMetadata("Type", "Non-Resx"); }
            }
            AssignedFilesWithCulture = withCulture;
            AssignedFilesWithNoCulture = withoutCulture;
        </Code>
    </Task>
</UsingTask>

请解释一下,您把这放在哪里了? - BlackOverlord
在项目文件中(右键单击项目,卸载,编辑,在底部粘贴) - Sense545

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接