4

I keep getting the error "Stream was not writable" whenever I try to execute the following code. I understand that there's still a reference to the stream in memory, but I don't know how to solve the problem. The two blocks of code are called in sequential order. I think the second one might be a function call or two deeper in the call stack, but I don't think this should matter, since I have "using" statements in the first block that should clean up the streams automatically. I'm sure this is a common task in C#, I just have no idea how to do it...

string s = "";

using (Stream manifestResourceStream =
    Assembly.GetExecutingAssembly().GetManifestResourceStream("Datafile.txt"))
{
    using (StreamReader sr = new StreamReader(manifestResourceStream))
    {
        s = sr.ReadToEnd();
    }
}

...

string s2 = "some text";

using (Stream manifestResourceStream =
    Assembly.GetExecutingAssembly().GetManifestResourceStream("Datafile.txt"))
{
    using (StreamWriter sw = new StreamWriter(manifestResourceStream))
    {
        sw.Write(s2);
    }
}

Any help will be very much appreciated. Thanks!

Andrew

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Andrew
  • 6,144
  • 10
  • 37
  • 54
  • Uhm.. that is not exactly entirely true. I have seem applications modify embedded resources. What they did it loaded the exe into a Stream and then encode it to ascii. When doing that you will notice your XML file will show. So what they did then was search for the index of the start of the XML file and somehow replaced the bytes in the executable with the new xml file. I don't know how they did it nor could I do it yet but I know it is possible. –  Nov 23 '10 at 04:35

3 Answers3

17

Embedded resources are compiled into your assembly, you can't edit them.

Joachim VR
  • 2,320
  • 1
  • 15
  • 24
  • 4
    Oops, thanks I didn't know that. Do you know if there's any way to write to a resource that's part of the program without having the data in a seperate file? – Andrew Sep 17 '10 at 14:52
  • I believe this is a security problem. I know in Windows 7 a program is not allowed to modify content in its Program Files directory. Windows plays some black magic with legacy software but this is generally considered bad practice. – Jordan Jun 26 '13 at 15:13
  • can a dll write to itself, though, when executed by another assembly? – DevDave Jul 31 '13 at 12:29
1

As stated above, embedded resources are read only. My recommendation, should this be applicable, (say for example your embedded resource was a database file, XML, CSV etc.) would be to extract a blank resource to the same location as the program, and read/write to the extracted resource.

Example Pseudo Code:

if(!Exists(new PhysicalResource())) //Check to see if a physical resource exists.
{
    PhysicalResource.Create(); //Extract embedded resource to disk.
}

PhysicalResource pr = new PhysicalResource(); //Create physical resource instance.

pr.Read(); //Read from physical resource.

pr.Write(); //Write to physical resource.

Hope this helps.

Additional:

Your embedded resource may be entirely blank, contain data structure and / or default values.

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
1

A bit late, but for descendants=) About embedded .txt:

Yep, on runtime you couldnt edit embedded because its embedded. You could play a bit with disassembler, but only with outter assemblies, which you gonna load in current context.

There is a hack if you wanna to write to a resource some actual information, before programm starts, and to not keep the data in a separate file.

I used to worked a bit with winCE and compact .Net, where you couldnt allow to store strings at runtime with ResourceManager. I needed some dynamic information, in order to catch dllNotFoundException before it actually throws on start. So I made embedded txt file, which I filled at the pre-build event.

like this:

cd $(ProjectDir)
dir ..\bin\Debug /a-d /b> assemblylist.txt

here i get files in debug folder

and the reading:

using (var f = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Market_invent.assemblylist.txt")))
        {
            str = f.ReadToEnd();
        }  

So you could proceed all your actions in pre-build event run some exes.

Enjoy! Its very usefull to store some important information and helps avoid redundant actions.

Roma Borodov
  • 596
  • 4
  • 10