GetManifestResourceStream 返回 NULL

这是一个 C # . NET 4.0应用程序:

我嵌入了一个文本文件作为资源,然后尝试在一个对话框中显示它:

    var assembly = Assembly.GetExecutingAssembly();
var resourceName = "MyProj.Help.txt";


using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
System.Windows.Forms.MessageBox.Show(result, "MyProj", MessageBoxButtons.OK);
}
}

解决方案是 MyProjSolution,可执行文件是 MyProj.exe。Txt 是一种嵌入式资源。但是,流为空。我试过 MyProjSolution。Help.txt 和 MyProjSolutions. MyProj。帮助。但似乎没有工作。

100204 次浏览

您可能需要在 GetManifestResourceStream参数中指定 txt 文件的路径,或者您可以尝试将 txt 文件与可执行文件放在同一个目录中。希望能帮上忙!

可以通过使用

//From the assembly where this code lives!
this.GetType().Assembly.GetManifestResourceNames()


//or from the entry point to the application - there is a difference!
Assembly.GetExecutingAssembly().GetManifestResourceNames()

调试时。这将列出您的代码所写入的程序集中嵌入的所有资源的所有(完全限定的)名称。

请参阅 MSDN 上的 Assembly. GetManifestResourceNames ()

只需复制相关的名称,并使用它来代替在变量“ resources Name”中定义的任何内容。

注意: 资源名称区分大小写,如果您错误地嵌入了资源文件,它将不会显示在调用 GetManifestResourceNames ()返回的列表中。另外——确保从正确的程序集读取资源(如果使用了多个程序集)——从当前正在执行的程序集而不是从引用的程序集获取资源非常容易。

编辑-. NET 核心
有关如何使用.NET Core 嵌入的详细信息,请参阅此 所以邮局

检索清单信息看起来是类似的-只需使用 this.GetType().GetTypeInfo().Assembly.GetManifestResourceNames()从执行代码的程序集中获取清单。

我还没有弄明白如何做相当于 Assembly.GetExecutingAssembly()的。NET 核心!如果有人知道-请让我知道,我会更新这个答案。

我有一个类似的问题,首先检查文件是否包含在您的项目中,然后转到属性并将该文件的构建操作设置为嵌入式资源。这招对我很管用。

只是个警告。

我不能访问我的文件作为一个嵌入式资源,即使我指定它是,即使它具有构建操作属性。浪费了我很多时间。我嵌入了一个 CSharp 代码文件。Txt 附加到它的名称后面(xxx.cs.txt)。由于某些原因,GetManifestResourceNames ()和 GetManifestResourceStream ()方法将看不到具有。以它的名字命名。

我把它简单地重命名为 xxx.txt,一切都很好。

真奇怪。

我也遇到了同样的问题,多亏了杰伊,我才在目录名中发现了连字符。

当您引用资源流时,ProjectName.ResourceFolder.Sub-Directory变成 ProjectName.ResourceFolder.Sub_Directory

下面是我的空值的原因。

Http://adrianmejia.com/blog/2011/07/18/cs-getmanifestresourcestream-gotcha/

如果资源“构建操作”属性没有设置为“嵌入资源”,则 GetManifestResourceStream方法将始终返回 NULL

在使用所有需要的文件设置此属性后,assembly.GetManifestResourceStream开始返回正确的流,而不是 NULL

在我的例子中,问题是寻找资源的代码位于与资源本身不同的项目中。

只能访问与代码位于同一项目中的资源。我认为我可以把我所有的资源在网页项目,但我需要在邮件项目的图像太。

希望这能帮到和我处境相同的人。

我发现打电话给 Assembly.GetExecutingAssembly().GetManifestResourceNames();非常有用。

    First Unload the project and click on edit the project file.


Inside the project file make sure that the item you are fetching from the assembly is included inside <EmbeddedResource> tag.


Eg:


<ItemGroup>
<EmbeddedResource Include="Template\ForExampleFile.html" />
</ItemGroup>




The files I added into the project were just in Content tag but not in the EmbeddedResource as shown below by default. Hence the stream was returning null.
<ItemGroup>
<Content Include="Template\ForExampleFile.html" />
</ItemGroup>

您需要卸载您的解决方案。然后编辑项目。找到您的文件夹后,修改如下:

<EmbeddedResource Include="yourpath" />

嵌入文件的 “建立行动”属性应设置为 “嵌入式资源”,以正确运行下面给出的代码行:

Stream stream = assembly.GetManifestResourceStream(resourceName)

右键单击文件,单击属性,然后将“ BuildAction”属性设置为“嵌入式资源”:

enter image description here

如果它有助于其他人,请确保从具有嵌入资源的同一程序集调用 Assembly.GetExecutingAssembly()行。

一个简单而流线型的解决方案是使用这个 基地类:

public class EmbededResourceReader
{
protected string LoadString(string fileName)
{
return LoadString(fileName, Encoding.UTF8);
}


protected string LoadString(string fileName, Encoding encoding)
{
var assembly = this.GetType().Assembly;
var resourceStream = assembly.GetManifestResourceStream($"{this.GetType().Namespace}.{fileName}");
using (var reader = new StreamReader(resourceStream, encoding))
{
return reader.ReadToEnd();
}
}
}

然后,在添加资源时,在同一个文件夹中创建一个阅读器 C # 类:

enter image description here

其中读者类 MyResource.cs 非常简单:

public class MyResource : EmbededResourceReader
{
public string LoadString() => LoadString($"{nameof(MyResource)}.txt");
}

因此,每个资源都有一个“影子”类,该类知道如何正确地读取它。

下面是如何读取代码中的资源:

var text = new MyResource().LoadString();

正如其他答案所建议的那样,不要忘记在资源文件的 BuildAction 属性中设置“嵌入式资源”。

这种统一解决方案的优点是

  1. 找到正确的资源全名,尤其是放在嵌套文件夹中时,更少的麻烦
  2. 当项目设置中的文件夹重命名为 OR 默认名称空间时,代码将不会中断

尽管 OP 是从同一个汇编中的资源获得 返回 NULL的,但是一些答案表明,当资源在另一个项目或汇编中时,无法检索到它们,这是 GetManifestResourceStream 返回 NULL 的合理原因。

这是不正确的,至少自2011年以来是这样; 正如我在其他地方的一些评论中指出的,Assembly. LoadFrom ()类型可以做到这一点,因此您可以访问另一个项目中的资源。

这里我有一个比较复杂的示例来说明; 这是我的测试设置:

enter image description here

通向另一个项目的路径:

enter image description here

在这里被捕获:

 var sharedXMLResource =
"D:\\My Documents\\Consultório Impressos\\DB Pacientes\\Teste\\TestesVariados\\WinFormFramework\\Read_Embedded_XML_File_CS\\bin\\Debug\\Read_Embedded_XML_File_CS.exe";

在 WinFormFramework 的 Form1.cs 上,我用

名称空间。文件夹。资源

就像这样:

StreamReader reader =
new StreamReader(Assembly.LoadFrom(sharedXMLResource).GetManifestResourceStream("Read_Embedded_XML_File_CS.SharedResources.ContactList.xml") ?? throw new InvalidOperationException());

结果显示在文本框中: enter image description here

我花了好几个小时才把它做好; 为此,我不得不在“即时窗口”中大量使用以下内容:

Environment.CurrentDirectory
AppDomain.CurrentDomain.BaseDirectory
System.Reflection.Assembly.GetExecutingAssembly().Location
System.Reflection.Assembly.GetAssembly(typeof(WinFormFramework.Program)).Location

希望能帮到别人