133

I would like to embed a text file in an assembly so that I can load the text without having to read it from disk, and so that everything I need is contained within the exe. (So that it's more portable)

Is there a way to do this? I assume something with the resource files?

And if you can, how do you do it and how do you programaticaly load the text into a string?

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
Adam Haile
  • 30,705
  • 58
  • 191
  • 286

7 Answers7

161

Right-click the project file, select Properties.

In the window that opens, go to the Resources tab, and if it has just a blue link in the middle of the tab-page, click it, to create a new resource.

enter image description here

Then from the toolbar above the tab-page, select to add a new text file, give it a name, it will be added to your project and opened up.

If you get this far, then in your code you can type in Resources.TheNameYouGaveTheTextFileHere and you can access its contents. Note that the first time you use the Resources class in a class, you need to add a using directive (hit Ctrl+. after typing Resources to get the menu to get VS to do it for you).

If something was unclear about the above description, please leave a comment and I'll edit it until it is complete or makes sense :)

David
  • 15,894
  • 22
  • 55
  • 66
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • 1
    What would the 'using' directive code look like, I'm struggling to make this work. I've added the solutions.txt as a resource, but it can't find Resources.solutions - I feel I'm missing the using directive. – Spedge Jun 13 '09 at 12:46
  • 3
    Ah-hah, all I needed to do was add a My. to the front (i.e. My.Resources.solutions) Simples! – Spedge Jun 13 '09 at 14:40
  • 3
    Adding a resource generates and includes `Properties\Resources.Designer.cs` with `namespace YourProjectRootNamespace.Properties`, so you have to use `YourProjectRootNamespace.Properties`. `ProjectRootNamespace` is defined in properties of your project in VisualStudio. – ilyaigpetrov Jun 09 '14 at 09:42
  • 2
    If I add a text file in this manner, and say that text file is part of my solution...if that file gets updated and I rebuild the assembly will the embedded resource also get updated? Or will I need to manually remove/re-add the file if I ever change it? – Peter Tirrell Jul 23 '15 at 15:54
  • 5
    Files are packaged into resources at compile time, not when you add them. You can freely change the file in any tool you like and rebuild, the changes will be part of your assembly. – Lasse V. Karlsen Jul 23 '15 at 15:56
43

In Visual Studio 2003, Visual Studio 2005 and possibly earlier versions (this works in 2008 as well) you can include the text file in your project, then in the 'Properties' panel, set the action to 'Embedded Resource'. Then you can access the file as a stream using Assembly.GetManifestResourceStream(string).

Other answers here are more convenient. I include this for completeness.

Note that this approach will work for embedding other types of files such as images, icons, sounds, etc...

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • 9
    Note: Use the namespace + filename as parameter for GetManifestResourceStream(), e.g. "MyNamespace.MyTextfile.txt". You can also call GetManifestResourceNames() to get a list of all names. – Stiefel Aug 25 '10 at 09:47
35

After embeding a text file, use that file any where in code like this...

global::packageName.Properties.Resources.ThatFileName
Narottam Goyal
  • 3,534
  • 27
  • 26
9

Here's what worked for me. (I needed to read contents of a file embedded into an executable .NET image file.)

Before doing anything, include your file into your solution in Visual Studio. (In my case VS 2017 Community.) I switched to the Solution Explorer, then right-clicked Properties folder, chose Add Existing Item and picked the file. (Say, FileName.txt.) Then while still in the Solution Explorer, right-click on the included file, select Properties, and pick Build Action as Embedded Resource.

Then use this code to read its bytes:

string strResourceName = "FileName.txt";

Assembly asm = Assembly.GetExecutingAssembly();
using( Stream rsrcStream = asm.GetManifestResourceStream(asm.GetName().Name + ".Properties." + strResourceName))
{
    using (StreamReader sRdr = new StreamReader(rsrcStream))
    {
        //For instance, gets it as text
        string strTxt = sRdr.ReadToEnd();
    }
}

Note, that in this case you do not need to add that file as a resource as was proposed in the accepted answer.

Andrew Cowenhoven
  • 2,778
  • 22
  • 27
c00000fd
  • 20,994
  • 29
  • 177
  • 400
4

Yes, you are correct - create a resource file. WHen you do that you don't need to "load" the string, it will be referenced as Resource.WhateverStringYouDefined.

Otávio Décio
  • 73,752
  • 17
  • 161
  • 228
2

Here is what I did:

  1. Added my files (resources) in Visual Studio by right-clicking on the project.
  2. Right click on every file you have added and change the "Build Type" to Embedded Resource.
  3. In order to access the resource:

    a. Got the current assembly using the function: GetExecutingAssembly()

    b. The resource that I added was a text file so I read it into a stream using GetManifestResourceStream(fileName). The way I accessed the file names is by calling GetManifestResourceNames()

    c. Now use a StreamReader() class to read to the end of file into a variable if that is what you want.

Pavan
  • 31
  • 2
0

Adding to Pavan's answer, to get the current assembly (in general section):

Assembly _assembly;

GetManifestResourceStream(fileName)(in code, where the read from resource is required):

try
{
    _assembly = Assembly.GetExecutingAssembly();
    _textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("*Namespace*.*FileName*.txt"));
}
catch
{
    Console.WritelLine("Error accessing resource!");
}
Narjis Hasan
  • 1
  • 1
  • 4