Roslyn将内容嵌入到程序集中

时间:2016-05-01 16:36:09

标签: c# .net resources roslyn

是否可以使用roslyn将content嵌入到程序集中?嵌入资源很有用,但无法弄清楚如何添加内容。我添加这样的资源:

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);
}

而不是在发出时传递:

EmitResult result = compilation.Emit(ms, manifestResources: resourceDescriptions.ToArray());

但我现在不添加其他类型的Build Actions

修改

content必须可以使用System.Windows.Application.LoadComponent(this, resourceLocater);加载。

编辑2

好的,出于测试目的,我添加.xaml和.baml,但我仍然收到消息, 找不到testusercontrol.xaml

以下是我添加这些文件的方式:

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());

我是否使用了错误的ressourceName(使用编辑3,这应该是肯定的)?

编辑3

我想我发生了什么问题。在程序集内部没有创建任何ressource目录。它应该是这样的:

Resource sample 01

这就是它目前的样子:

Resource sample 02

但是如何使用roslyn创建这些目录?

编辑4

好的,嵌入资源可以使用以下代码:

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());

ILSpy

中也可以看到它

Resource sample 03

但无法找到testusercontrol.xaml的消息框仍然存在。我在做什么另外错了?

编辑5 - 解决方案

现在有效!步骤进行:

首先:在命名空间和程序集名称下添加资源,在任何其他情况下,roslyn都会遇到麻烦:

// 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);
}

第二:将资源添加为流:

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);
}
第三:快乐

谢谢大家!

1 个答案:

答案 0 :(得分:2)

要么我完全误解了这个问题,要么你要求一个方形三角形。

“内容”和“资源”之间的区别在于内容位于程序集之外,资源嵌入到程序集中。 System.Windows.Application.LoadComponent无法加载资源,只能加载内容。

因此,原则上你所要求的是不可能的。