.Net Core库中的嵌入式资源


75

我刚刚开始研究.Net Core,但看不到经典资源和任何看起来像资源的东西。在经典的.Net类库中,我可以将带有某些脚本的文本过滤添加到我的项目中,然后再将这些文件添加到项目的资源中。之后,我可以通过以下方式轻松使用它:

Connection.Execure(Properties.Resources.MySuperScript);

我看到.Net Core库中没有这种功能,至少我没有看到。.Net Core中是否有替代方法可以将某些静态数据作为嵌入式资源存储在库中?以及如何使用它(如果存在)?


2
尚不支持资源。也许使用JSON或XML文件?
Gerardo Grignoli

我使用了用于SQL脚本的资源,它们包含诸如引号之类的特殊符号,因此使用JSON并不方便,因为应将这些符号更改为转义序列。以这种形式阅读和修复脚本并不方便。:(
Don Tomato


这个答案:stackoverflow.com/a/57811919/156991是今天最好的。
Mike Eshva '19

Answers:


108

更新:

.NET Core 1.1和更高版本已删除project.json并返回到.csproj文件。这会更改步骤2,但变化不大。必要的行非常相似:

<ItemGroup>
  <Content Remove="_fonts/OpenSans.ttf" />
  <Content Remove="_fonts/OpenSans-Bold.ttf" />
  <Content Remove="_fonts/OpenSans-Italic.ttf" />
</ItemGroup>
<ItemGroup>
  <EmbeddedResource Include="_fonts/OpenSans.ttf" />
  <EmbeddedResource Include="_fonts/OpenSans-Bold.ttf" />
  <EmbeddedResource Include="_fonts/OpenSans-Italic.ttf" />
</ItemGroup>

可能有类似的*.tff形式。未经证实。

步骤1和3保持不变。


要在.NET Core 1.0项目中使用嵌入式资源,请执行以下操作:

  1. 照常添加您的嵌入式文件。

    示例:名为“ _fonts”的目录上的一些FONT文件

    在此处输入图片说明

  2. 修改“ project.json”以包括相关资源。

    就我而言:

     "buildOptions": {
        "embed": {
          "include": [
            "_fonts/*.ttf"    
          ]
        } 
      },
    
  3. 用代码访问嵌入式资源。

    var assembly = typeof(MyLibrary.MyClass).GetTypeInfo().Assembly;
    Stream resource = assembly.GetManifestResourceStream("MyLibrary._fonts.OpenSans.ttf");
    

    关键是在GetManifestResourceStream通话中使用正确的名称。您必须使用[assembly name].[directory].[file name]


34
为确保获取正确的资源,请评估目标程序集中的所有可用资源string[] names = assembly.GetManifestResourceNames();
Luka

1
这对我有用,但是仍然使用位于已执行程序集根目录中的文件路径结束。我有两个dll,一个用于API,一个用于CSV。API是运行的库。CSV包含我需要阅读的文件。即使文件列出为“ Mylibrary.folder.file”(即“ CSV.csv.somefile.csv”),它也会尝试读取“ solution / API / somefile.csv”。我希望它读取的路径是“ solution / CSV / csv / somefile.csv”。关于如何保留装配体内相对路径的任何建议?
melwil

谢谢@Luka,您的评论帮助我确定了嵌入式资源的实际名称!
艾伦·鲁弗洛

@Zartag所说的是有意义的,除了使用路径无法访问文件这一事实外,主要解决方案是有效的,但是在某些用例中,没有
必要

3
看起来资源名称的格式使用程序集的默认名称空间,而不是程序集名称。但是,如上所述,仍以点分隔。
tiwahu

50

现在project.json已弃用,您必须在.csproj文件中指定它。

<ItemGroup>
    <EmbeddedResource Include="_fonts\*.ttf" />
</ItemGroup>

您可以使用如图所示的通配符,或仅明确列出文件。


8
如果没有随后如何获取数据的详细信息,这用处不大。
布朗达hl

编译后磁盘上的资源在哪里?我希望在/ bin文件夹中的某处找到* .ttf。
Jim Aho

4
@JimAho文件嵌入在程序集中。
德鲁·诺阿克斯

@Brondahl的问题是关于嵌入资源的,这是怎么做的。:) OP可能知道从这里出发。对于其他人寻找如何做到这一点,这里有涉及与xUnit的测试示例实现:patriksvensson.se/2017/11/...
佐尼Skovdal

24

使用.Net Core 2.0或更高版本的较新版本,有一个专门的类EmbeddedFileProvider可以抽象嵌入式文件的读取。要使用它,请将Microsoft.Extensions.FileProviders.Embedded包添加到您的应用程序中:

dotnet add package Microsoft.Extensions.FileProviders.Embedded

EmbeddedFileProvider允许您创建一个流阅读器,并使用根据您的情况:

var embeddedProvider = new EmbeddedFileProvider(Assembly.GetExecutingAssembly());
using (var reader = embeddedProvider.GetFileInfo("yourfile.ext").CreateReadStream())
{
  // some logic with stream reader
}

1
这似乎很有希望,但是我在子文件夹中的文件有问题。我最终使用string[] names = assembly.GetManifestResourceNames();上面提到的Luka完成了自己的匹配逻辑 。
JackMorrissey

12

人们通常已经回答了这个问题,所以这是将答案简化为简单的结果。

使用以下代码之前,应将文件作为嵌入式资源添加到.csproj / project.json

用法

var myJsonFile = ReadManifestData<Tests>("myJsonFile.json");
  1. 参数:嵌入式文件名;类型:目标资源的程序集中的任何类
  2. 寻找具有该名称的嵌入式资源
  3. 返回字符串值

方法

public static string ReadManifestData<TSource>(string embeddedFileName) where TSource : class
{
    var assembly = typeof(TSource).GetTypeInfo().Assembly;
    var resourceName = assembly.GetManifestResourceNames().First(s => s.EndsWith(embeddedFileName,StringComparison.CurrentCultureIgnoreCase));

    using (var stream = assembly.GetManifestResourceStream(resourceName))
    {
        if (stream == null)
        {
            throw new InvalidOperationException("Could not load manifest resource stream.");
        }
        using (var reader = new StreamReader(stream))
        {
            return reader.ReadToEnd();
        }
    }
}

4

我尚未在文档中对此进行确认,但是对我来说,它似乎是自动生成的资源代码,用于检索在Resource.Designer.cs中找到的嵌入式文件,现在在.NET Core 3.1中再次起作用。现在,我可以简单地通过调用返回一个Bitmap对象的Properties.Resources.MyImageName来检索嵌入的jpg。


streamreader仅检索字符。如果您的资源文件是基于字符的,这将起作用
Golden Lion
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.