【问题标题】:Roslyn embedd content into assemblyRoslyn 将内容嵌入到程序集中
【发布时间】:2017-07-29 20:57:23
【问题描述】:

是否可以使用 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

我想我出了什么问题。程序集内部没有创建资源目录。它应该是这样的:

这就是它目前的样子:

但是如何使用 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中也可见:

但是找不到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);
}

第三:快乐

谢谢大家!

【问题讨论】:

  • 为什么你在你的问题中写下你的答案。回答你的问题

标签: c# .net resources roslyn


【解决方案1】:

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

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

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

【讨论】:

  • 但是 MS 正在将 System.Windows.Application.LoadComponent 嵌入到它的 .g.cs 文件中。但我从未在bin\debugrelease 目录中看到它们。所以它必须可以从程序集内部加载。还有其他一些Build ActionPage 我可以与Roslyn 一起使用吗?非常感谢!
  • 所以,是的,你是对的。这些被嵌入为 YourNamespace.g.resources,它本身就是一个 resource container,其中包含所有编译到 baml's 的 xaml
  • 感谢您的快速回复 :) 我编辑了最初的帖子并添加了更多详细信息。我认为我使用了错误的资源名称,但无法弄清楚它应该是什么样子。你看到那里有失败吗?出于测试目的,我同时添加了 xaml 和 baml
  • 是的,进展顺利。我认为您需要创建 .resource 文件,如我上面评论中的第一个链接中所述。您需要将 baml 放入此文件中,最后以与您现在相同的方式将文件添加到资源中,名称为 YourNamespace.g.resources。
  • 好的,添加资源完美,但错误仍然存​​在。我现在做错了什么。谢谢你的耐心:)(我编辑了我的帖子)
猜你喜欢
  • 2010-12-03
  • 1970-01-01
  • 2021-12-13
  • 2010-10-08
  • 2012-06-01
  • 2018-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多