darkstarohio
darkstarohio

Reputation: 23

Having issues extracting an embedded resource from C# application

The idea here is to extract a batch file from an embedded resource to a temporary directory on the C drive, then run that extracted batch file. The issue I'm running into is an error of "Object reference not set to an instance of an object."

The code is:

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);
            }
        }
    }

The error occurs on this line:

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

Upvotes: 0

Views: 1029

Answers (3)

Mechanical Object
Mechanical Object

Reputation: 666

How is the following working for you?

    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);
                        }
                    }
                }

            }
       }

Upvotes: 0

Rhys Bevilaqua
Rhys Bevilaqua

Reputation: 2167

It sounds like the stream doesn't get returned or it isn't reporting length.

Also, don't read the whole stream at once, it's not very memory efficient and isn't the best pattern to follow when you start using network streams or large files which may not actually report their actual length.

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);
        }
    }
}

Upvotes: 0

Damith
Damith

Reputation: 63065

if you embedded resource then it will generate static method to to get content of embedded file content, internally it call the ResourceManager.GetString method, so try below

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

Upvotes: 1

Related Questions