如何防止嵌入式资源的资源组合生成 [英] How to prevent resource assembly generation for embedded resources
问题描述
我有一个项目,其中嵌入了一些文件,其中两个以 .SMS.something
结尾.编译项目时,即使我没有指定要使用卫星程序集的任何地方,也会生成用于"SMS"文化的卫星程序集,这甚至是一种文化吗?
I have a project which embeds some files into it, two of which ends with .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?
我到处搜索了解释,但茫然不知所措.我发现的唯一结果是,人们试图将其用于实际区域性的资源程序集嵌入到其可执行文件中,但这不是我的情况.我只想将所有嵌入资源(只有一种语言)放在同一程序集中.
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.
如何防止这种自动生成的卫星程序集,或者指定SMS不是一种文化?
How can I prevent this automatic generation of satellite assemblies, or specify that SMS is not a culture?
推荐答案
我通过查看Microsoft.Common.targets和Microsoft.CSharp.targets并找出了哪些任务,以一种非常hacky的完美工作方式解决了此问题实际上对资源进行了排序并为其命名.
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.
因此,我使用将ManifestResourceName和LogicalName设置为符合我想要的方式的一项来覆盖CreateCSharpManifestResourceName任务:
So I override the CreateCSharpManifestResourceName task with one that set the ManifestResourceName and LogicalName to be something along the lines of what i want:
<!-- 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
.
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 e.g. /path.to/my.SMS.file
.
然后我用一个只返回没有文件具有任何区域性的文件来覆盖AssignCulture任务,并向它们添加< WithCulture> false</WithCulture>
(这非常适合我情况):
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):
<!-- 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 < 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>
这篇关于如何防止嵌入式资源的资源组合生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!