简体   繁体   English

如何防止嵌入资源的资源组件生成

[英]How to prevent resource assembly generation for embedded resources

I have a project which embeds some files into it, two of which ends with .SMS.something . 我有一个项目,其中嵌入了一些文件,其中两个以.SMS.something When the project is compiled, a satellite assembly for the "SMS" culture is generated even though I have not specified anywhere that I want to use satellite assemblies, and is it even a culture? 编译项目时,即使我没有指定任何我想要使用附属程序集的文件,也会生成“SMS”文化的附属程序集,它甚至是文化?

I have searched all over the place for an explanation, but I am at a loss. 我到处寻找解释,但我不知所措。 The only things I found were people trying to embed their resource assemblies for actual cultures into their executable, but this is not my case. 我发现的唯一的事情是人们试图将他们的资源集合嵌入到他们的可执行文件中,但这不是我的情况。 I just want to have all my embedded resources, which are only in one language, to be in the same assembly. 我只想让我所有的嵌入式资源(只有一种语言)在同一个程序集中。

How can I prevent this automatic generation of satellite assemblies, or specify that SMS is not a culture? 如何防止自动生成附属程序集,或指定SMS不是文化?

I managed to solve this in a very hacky put perfectly working way by looking in the Microsoft.Common.targets and Microsoft.CSharp.targets and figuring out what tasks actually sorted the resources and gave them names. 我设法通过查看Microsoft.Common.targets和Microsoft.CSharp.targets以及确定哪些任务实际对资源进行了排序并给出了名称,以一种非常hacky的方式解决了这个问题。

So I override the CreateCSharpManifestResourceName task with one that set the ManifestResourceName and LogicalName to be something along the lines of what i want: 所以我用一个将ManifestResourceName和LogicalName设置为我想要的东西来覆盖CreateCSharpManifestResourceName任务:

<!-- 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>

As an added bonus, the files i embed get their actual path (only with \\ replaced with / ) as their resource name, and thus can be easily looked up using Assembly.GetManifestResourceStream(x) where x would be eg /path.to/my.SMS.file . 作为一个额外的好处,我嵌入的文件获取他们的实际路径(仅用\\替换为/ )作为他们的资源名称,因此可以使用Assembly.GetManifestResourceStream(x)轻松查找,其中x将是例如/path.to/my.SMS.file

And then I override the AssignCulture task with one that just returns that none of the files had any culture, and adds <WithCulture>false</WithCulture> to them (which fits perfectly in my case): 然后我用一个只返回没有任何文件的文件来覆盖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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM