How to prevent generation of resource assembly for embedded resources
I have a project that inserts multiple files into it, two of which end in .SMS.something
. When the project is compiled, a compilation of satellites for the "SMS" culture is created, although I have not indicated anywhere that I want to use satellite assemblies, and is this even a culture?
I have searched all over the place for an explanation, but I am at a loss. The only thing I have found is people trying to inject their real culture resource assemblies into their executable, but this is not my case. I just want all of the embedded resources that are in only one language to be in the same assembly.
How can I prevent the automatic creation of satellite assemblies or indicate that SMS is not a crop?
source to share
I was able to solve this in a very hacky way, working fine by looking at Microsoft.Common.targets and Microsoft.CSharp.targets and figuring out which tasks actually sorted the resources and gave them names.
So, I am overriding the CreateCSharpManifestResourceName task with the one that sets the ManifestResourceName and LogicalName to be something like the strings 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>
As an added bonus, the files I embed get their actual path (only s \
replaced by /
) as their resource name and therefore can be easily traced with Assembly.GetManifestResourceStream(x)
where x would be for example. /path.to/my.SMS.file
...
And then I override the AssignCulture task to simply return that none of the files have any culture and add to them <WithCulture>false</WithCulture>
(which is perfect 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>
source to share