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

时间:2014-12-03 12:44:10

标签: c# .net msbuild culture satellite-assembly

我有一个项目,其中嵌入了一些文件,其中两个文件以.SMS.something结尾。 在编译项目时,用于" SMS"即使我没有指定任何我想要使用卫星装配的文化,它也会产生文化?它甚至是一种文化?

我到处寻找解释,但我不知所措。我发现的唯一的事情是人们试图将他们的资源集合嵌入到他们的可执行文件中,但这不是我的情况。我只想让我所有的嵌入式资源(只有一种语言)在同一个程序集中。

如何防止自动生成附属程序集,或指定SMS不是文化?

1 个答案:

答案 0 :(得分:4)

我设法通过查看Microsoft.Common.targets和Microsoft.CSharp.targets以及确定哪些任务实际对资源进行了排序并为其命名,以一种非常hacky完美的方式解决了这个问题。

所以我用一个将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>

作为额外奖励,我嵌入的文件会将其实际路径(仅\替换为/)作为其资源名称,因此可以使用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>