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

Sen*_*545 3 .net c# msbuild culture satellite-assembly

我有一个项目,其中嵌入了一些文件,其中两个以.SMS.something. 编译项目时,即使我没有指定要使用附属程序集的任何地方,也会生成“SMS”文化的附属程序集,它甚至是一种文化吗?

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

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

Sen*_*545 5

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

因此,我使用将 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>
Run Code Online (Sandbox Code Playgroud)

作为额外的好处,我嵌入的文件将它们的实际路径(仅用\替换为/)作为它们的资源名称,因此可以使用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>
Run Code Online (Sandbox Code Playgroud)