Is it possiblem to embedd content
into an assembly using roslyn? Embedding resources works great, but can't figure out how to add content. I add resources like this:
foreach (string file in Directory.GetFiles(inputPath).Where(item => item.EndsWith(".xaml")))
{
var resourceDescription = new ResourceDescription(
Path.GetFileName(file.ToLower()),
() => File.OpenRead(file.ToLower()),
true);
resourceDescriptions.Add(resourceDescription);
}
And than pass it when emitting:
EmitResult result = compilation.Emit(ms, manifestResources: resourceDescriptions.ToArray());
But I don't now to add other type of Build Actions
.
EDIT
The content
must be loadable using System.Windows.Application.LoadComponent(this, resourceLocater);
.
EDIT 2
Ok, for testing purpose I add both, .xaml and .baml, but I still get the message,
that testusercontrol.xaml
was not found.
Here is how I'm adding those files:
List<ResourceDescription> resourceDescriptions = new List<ResourceDescription>();
foreach (string file in Directory.GetFiles(outputPath).Where(item => item.EndsWith(".baml")))
{
var resourceDescription = new ResourceDescription(
string.Format("{0}.g.{1}", RootNamespace, Path.GetFileName(file.ToLower())),
Path.GetFileName(file.ToLower()),
() => File.OpenRead(file.ToLower()),
true);
resourceDescriptions.Add(resourceDescription);
}
foreach (string file in Directory.GetFiles(inputPath).Where(item => item.EndsWith(".xaml")))
{
var resourceDescription = new ResourceDescription(
string.Format("{0}.g.{1}", RootNamespace, Path.GetFileName(file.ToLower())),
Path.GetFileName(file.ToLower()),
() => File.OpenRead(file.ToLower()),
true);
resourceDescriptions.Add(resourceDescription);
}
EmitResult result = compilation.Emit(ms, manifestResources: resourceDescriptions.ToArray());
Do I use a wrong ressourceName
(With edit 3, this should be yes)?
EDIT 3
I think I got whats going wrong. There are no ressource directories created in inside of the assembly. That is how it should look:
And that is how it looks currently:
But how can i create those directories using roslyn?
EDIT 4
Ok, embedding the resources works with the following code:
string resourcePath = string.Format("{0}{1}.g.resources", outputPath, RootNamespace);
ResourceWriter rsWriter = new ResourceWriter(resourcePath);
foreach (string file in Directory.GetFiles(outputPath).Where(item => item.EndsWith(".baml")))
{
var fileName = Path.GetFileName(file.ToLower());
var data = File.ReadAllBytes(file);
rsWriter.AddResource(fileName, data);
}
foreach (string file in Directory.GetFiles(inputPath).Where(item => item.EndsWith(".xaml")))
{
var fileName = Path.GetFileName(file.ToLower());
var data = File.ReadAllBytes(file);
rsWriter.AddResource(fileName, data);
}
rsWriter.Generate();
rsWriter.Close();
var resourceDescription = new ResourceDescription(
string.Format("{0}.g.resources", RootNamespace),
() => File.OpenRead(resourcePath),
true);
resourceDescriptions.Add(resourceDescription);
EmitResult result = compilation.Emit(ms, manifestResources: resourceDescriptions.ToArray());
It is also visible in ILSpy
:
But the message box, that testusercontrol.xaml
could not be found is still existing. What am I doing additionaly wrong?
EDIT 5 - SOLUTION
It works now! Steps:
First: Add the resource under the namespace AND assembly name, in any other case roslyn makes some trouble:
// Add ressource under the namespace AND assembly
var resourceDescription = new ResourceDescription(
string.Format("{0}.g.resources", RootNamespace),
() => File.OpenRead(resourcePath),
true);
resourceDescriptions.Add(resourceDescription);
if (RootNamespace != assemblyName)
{
resourceDescription = new ResourceDescription(
string.Format("{0}.g.resources", assemblyName),
() => File.OpenRead(resourcePath),
true);
resourceDescriptions.Add(resourceDescription);
}
Second: Add the resource as a stream:
foreach (string file in Directory.GetFiles(outputPath).Where(item => item.EndsWith(".baml")))
{
var fileName = Path.GetFileName(file.ToLower());
var data = File.OpenRead(file);
rsWriter.AddResource(fileName, data, true);
}
Third: Be happy
Thank you all!
Either I completely misunderstood the question, or you are asking for a square triangle.
The difference between "content" and "resource" is that content lives outside of an assembly, and resource is embedded into assembly. System.Windows.Application.LoadComponent
cannot load resources, it can only load content.
Thus, what you are asking for is impossible in principle.
来源:https://stackoverflow.com/questions/36969090/roslyn-embedd-content-into-assembly