3

いくつかのファイルを埋め込むプロジェクトがあり、そのうちの 2 つは.SMS.something. プロジェクトがコンパイルされると、"SMS" カルチャのサテライト アセンブリが生成されますが、サテライト アセンブリを使用する場所をどこにも指定していません。それはカルチャですか?

説明を求めてあちこち検索しましたが、途方に暮れています。私が見つけたのは、実際のカルチャのリソース アセンブリを実行可能ファイルに埋め込もうとしている人々だけでしたが、これは私の場合ではありません。私は、1 つの言語のみであるすべての埋め込みリソースを同じアセンブリに入れたいだけです。

このサテライト アセンブリの自動生成を防止したり、SMS がカルチャではないことを指定したりするにはどうすればよいですか?

4

1 に答える 1

5

Microsoft.Common.targets と Microsoft.CSharp.targets を調べて、どのタスクが実際にリソースを並べ替えて名前を付けたかを突き止めることで、非常にハックな完全に機能する方法でこれを解決することができました。

そのため、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>

追加のボーナスとして、私が埋め込んだファイルは、リソース名として実際のパス ( に\置き換えられたもののみ) を取得するため、 x がどこにあるか/を使用して簡単に検索できます。Assembly.GetManifestResourceStream(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>
于 2014-12-04T08:01:59.117 に答える