如何写入嵌入式资源?

4
每当我尝试执行以下代码时,都会收到“Stream was not writable”的错误。我知道在内存中仍然存在对流的引用,但我不知道如何解决这个问题。这两个代码块按顺序调用。我认为第二个代码块可能是函数调用或更深层次的调用堆栈,但我认为这并不重要,因为我在第一个代码块中有“using”语句,应该可以自动清理流。我相信这是C#中常见的任务,但我不知道如何做...
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);
    }
}

任何帮助都将不胜感激。谢谢! 安德鲁

嗯,那不完全是真的。我见过应用程序修改嵌入式资源。他们所做的是将exe加载到流中,然后将其编码为ascii。这样做时,您会注意到您的XML文件会显示出来。然后他们搜索XML文件开始的索引,并以某种方式用新的xml文件替换可执行文件中的字节。我不知道他们是如何做到的,也不能做到,但我知道这是可能的。 - user516970
3个回答

17

嵌入资源被编译进你的程序集,无法进行编辑。


4
哎呀,谢谢你告诉我这个。你知道是否有办法写入程序中的资源而不必将数据保存在单独的文件中吗? - Andrew
我认为这是一个安全问题。在Windows 7中,程序不被允许修改其Program Files目录中的内容。Windows会对旧版软件进行一些黑魔法处理,但这通常被视为不良实践。 - Jordan
一个 DLL 能否在被另一个程序集执行时写入自身? - DevDave

1
有点晚了,但对于后代们=) 关于嵌入式.txt: 是的,在运行时你不能编辑嵌入式文件,因为它是嵌入式的。你可以试着用反汇编器玩一下,但只能处理外部程序集,而这些程序集会在当前上下文中加载。
如果你想在程序开始前向资源写入一些实际信息,而不是将数据保存在单独的文件中,那么有一个技巧可用。
我曾经使用过winCE和紧凑版.Net,在这些平台上你不能允许在ResourceManager中存储字符串。我需要一些动态信息,以便在程序开始前捕获dllNotFoundException异常。 所以我制作了一个嵌入式txt文件,在预构建事件中填充它。
像这样:
cd $(ProjectDir)
dir ..\bin\Debug /a-d /b> assemblylist.txt

在这里,我获取调试文件夹中的文件,并进行读取:
using (var f = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Market_invent.assemblylist.txt")))
        {
            str = f.ReadToEnd();
        }  

所以你可以在预构建事件中运行一些exe文件来执行所有操作。

享受吧!这非常有用,可以存储一些重要信息并帮助避免冗余操作。


1
如上所述,嵌入式资源是只读的。如果适用的话(例如您的嵌入式资源是数据库文件、XML、CSV等),我的建议是将一个空白资源提取到程序相同的位置,并对提取的资源进行读/写操作。
示例伪代码:
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.

希望这能有所帮助。
附加信息:
您的嵌入式资源可能完全为空,包含数据结构和/或默认值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接