C#:写/读其他可执行文件资源

时间:2017-02-20 23:10:28

标签: c# resources

应用 A 将一些数据写入可执行文件 B ,以便可执行文件 B 可以访问此数据

如何将资源写入/读取到另一个可执行文件。

只是一个基本答案

我发现了一段代码,用于将资源写入应用程序,但它无法正常工作,但我无法检索数据:

public class Packer : IDisposable
{
    private static byte[] MAGIC_NUMBER = { 0x44, 0x61, 0x6c, 0x65, 0x6b, 0x4c, 0x75, 0x63 };

    private Stream inStream;

    public Packer(string filename, bool openReadonly = false)
    {
        inStream = File.Open(filename, FileMode.Open, openReadonly ? FileAccess.Read : FileAccess.ReadWrite, openReadonly ? FileShare.Read : FileShare.None);
    }

    public byte[] ReadData(int index)
    {
        byte[] mn_buf = new byte[MAGIC_NUMBER.Length];
        byte[] len_buf = new byte[sizeof(Int32)];
        int data_len = 0;
        inStream.Seek(0, SeekOrigin.End);
        for (int i = 0; i <= index; ++i)
        {
            inStream.Seek(-MAGIC_NUMBER.Length, SeekOrigin.Current);
            inStream.Read(mn_buf, 0, MAGIC_NUMBER.Length);
            inStream.Seek(-MAGIC_NUMBER.Length, SeekOrigin.Current);
            for (int j = 0; j < MAGIC_NUMBER.Length; ++j)
            {
                if (mn_buf[j] != MAGIC_NUMBER[j])
                {
                    throw new IndexOutOfRangeException("Not enough data.");
                }
            }
            inStream.Seek(-sizeof(Int32), SeekOrigin.Current);
            inStream.Read(len_buf, 0, sizeof(Int32));
            inStream.Seek(-sizeof(Int32), SeekOrigin.Current);
            data_len = BitConverter.ToInt32(len_buf, 0);
            inStream.Seek(-data_len, SeekOrigin.Current);
        }
        byte[] data = new byte[data_len];
        inStream.Read(data, 0, data_len);
        return data;
    }

    public void AddData(byte[] data)
    {
        inStream.Seek(0, SeekOrigin.End);
        inStream.Write(data, 0, data.Length);
        inStream.Write(BitConverter.GetBytes(data.Length), 0, sizeof(Int32));
        inStream.Write(MAGIC_NUMBER, 0, MAGIC_NUMBER.Length);
    }

    public void Dispose()
    {
        inStream.Dispose();
    }
}

(我不知道如何缩小范围)

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以通过

从任何程序集中读取资源
  1. 使用Reflection

  2. 获取对装配的引用
  3. 将程序集作为构造函数参数传递给新的ResourceManager.

  4. 示例:

    var asm = System.Reflection.Assembly.LoadFrom("External.Resources.exe");
    var manifests = asm.GetManifestResourceNames();
    
    foreach (var s in manifests)
    {
        var rm = new ResourceManager(s, asm);
        var rs = rm.GetResourceSet(CultureInfo.CurrentCulture, true, true);
        foreach (DictionaryEntry r in rs)
        {
            Console.WriteLine(String.Format("Key: {0}\tValue:{1}", r, r.Key, r.Value); 
        }
    }
    

    写资源是另一回事。如果资源包含在程序集中,则表示已编译该资源。除非您的代码能够编译资源,否则无法将资源注入外部程序集。

    可以使用ResGen.exe将资源编译到第三个​​文件(.resource.扩展名)(你必须产生一个单独的过程),但您仍然需要编译项目以将资源注入到程序集中。

    如果您一心想更新原始程序集,可以使用/resource开关生成一个运行ilasm.exe的新进程(理论上,它会将.res文件注入到程序集中) )。您需要设置一个非常复杂的工作流来生成.res文件,将其放入已编译的程序集中,并替换原始程序集,如果程序集已签名,那么您还需要私钥。