Возникли проблемы с извлечением встроенного ресурса из приложения C#

Идея состоит в том, чтобы извлечь пакетный файл из встроенного ресурса во временный каталог на диске C, а затем запустить этот извлеченный пакетный файл. Проблема, с которой я сталкиваюсь, - это ошибка «Ссылка на объект не указывает на экземпляр объекта».

Код:

public static void ExtractResource()
    {
        using (Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(Namespace.Properties.Resources.Backup))
        {
            byte[] buffer = new byte[s.Length];
            s.Read(buffer, 0, buffer.Length);
            using (var sw = new BinaryWriter(File.Open(@"C:\test.bat", FileMode.OpenOrCreate)))
            {
                sw.Write(buffer);
            }
        }
    }

Ошибка возникает в этой строке:

byte[] buffer = new byte[s.Length];

person darkstarohio    schedule 19.07.2013    source источник
comment
Согласно документу. Ресурс манифеста; или null, если во время компиляции ресурсы не были указаны или если ресурс не виден вызывающей стороне.   -  person Taras Alenin    schedule 19.07.2013
comment
@darkstarohio каковы отзывы об этих предложениях?   -  person Mechanical Object    schedule 28.07.2013


Ответы (3)


если вы внедрили ресурс, то он сгенерирует статический метод для получения содержимого встроенного содержимого файла, внутри он вызовет метод ResourceManager.GetString, поэтому попробуйте ниже

using (var sw = new BinaryWriter(File.Open(@"C:\test.bat", FileMode.OpenOrCreate)))
{
   writer.Write(Namespace.Properties.Resources.Backup);
}
person Damith    schedule 19.07.2013

Похоже, поток не возвращается или не сообщает длину.

Кроме того, не читайте весь поток сразу, это не очень эффективно использует память и не является лучшим шаблоном для подражания, когда вы начинаете использовать сетевые потоки или большие файлы, которые могут фактически не сообщать о своей фактической длине.

public void WriteResrouce(string resourcePath, string targetPath)
{
    var buffer = new byte[64 * 1024]; //i've picked 64k as a reasonable sized block
    using (Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcePath))
    using (var sw = new BinaryWriter(File.Open(targetPath, FileMode.OpenOrCreate)))
    {
        var readCount = -1;
        while (0 < (readCount = s.Read(buffer, 0, buffer.Length)))
        {
            sw.Write(buffer, 0, readCount);
        }
    }
}
person Rhys Bevilaqua    schedule 19.07.2013

Как следующее работает для вас?

    public static  class Program
        {
            public static void Main()
            {
                ExtractResource();
            }

            public static void ExtractResource()
            {
                //replace your embedded file by yours 
                using (var inputStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication1.XMLFile1.xml"))
                {
                    using(var outputStream = File.Create(@"D:\test.bat"))
                    {
                        /// fix your buffer size 8192,4096 etc.
                        var buffer = new byte[8192];

                        int numberOfBytesRead;
                        while (inputStream != null && (numberOfBytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            outputStream.Write(buffer, 0, numberOfBytesread);
                        }
                    }
                }

            }
       }
person Mechanical Object    schedule 19.07.2013