Load Resource as Byte Array Programmaticaly in C++

load resource as byte array programmatically

The process is described in How to embed and access resources by using Visual C#.

Essentially it requires use of reflection, using the Assembly class.

Stream imageStream = 
currentAssembly.GetManifestResourceStream("Resources.logo_foot.png");

See How to convert an Stream into a byte[] in C#? for details of how to get a byte[] from a Stream.

Load resource as byte array programmaticaly in C++

To obtain the byte information of the resource, the first step is to obtain a handle to the resource using FindResource or FindResourceEx. Then, load the resource using
LoadResource. Finally, use LockResource to get the address of the data and access SizeofResource bytes from that point. The following example illustrates the process:

HMODULE hModule = GetModuleHandle(NULL); // get the handle to the current module (the executable file)
HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(RESOURCE_ID), RESOURCE_TYPE); // substitute RESOURCE_ID and RESOURCE_TYPE.
HGLOBAL hMemory = LoadResource(hModule, hResource);
DWORD dwSize = SizeofResource(hModule, hResource);
LPVOID lpAddress = LockResource(hMemory);

char *bytes = new char[dwSize];
memcpy(bytes, lpAddress, dwSize);

Error handling is of course omitted for brevity, you should check the return value of each call.

How to Read an embedded resource as array of bytes without writing it to disk?

You are actually already reading the stream to a byte array, why not just stop there?

public static byte[] ExtractResource(String filename)
{
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
using (Stream resFilestream = a.GetManifestResourceStream(filename))
{
if (resFilestream == null) return null;
byte[] ba = new byte[resFilestream.Length];
resFilestream.Read(ba, 0, ba.Length);
return ba;
}
}

edit: See comments for a preferable reading pattern.

How do I convert a Stream into a byte[] in C#?

Call next function like

byte[] m_Bytes = StreamHelper.ReadToEnd (mystream);

Function:

public static byte[] ReadToEnd(System.IO.Stream stream)
{
long originalPosition = 0;

if(stream.CanSeek)
{
originalPosition = stream.Position;
stream.Position = 0;
}

try
{
byte[] readBuffer = new byte[4096];

int totalBytesRead = 0;
int bytesRead;

while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
{
totalBytesRead += bytesRead;

if (totalBytesRead == readBuffer.Length)
{
int nextByte = stream.ReadByte();
if (nextByte != -1)
{
byte[] temp = new byte[readBuffer.Length * 2];
Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
readBuffer = temp;
totalBytesRead++;
}
}
}

byte[] buffer = readBuffer;
if (readBuffer.Length != totalBytesRead)
{
buffer = new byte[totalBytesRead];
Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
}
return buffer;
}
finally
{
if(stream.CanSeek)
{
stream.Position = originalPosition;
}
}
}

Is it possible to execute a embedded resource?

For managed assemblies, this is easy to do. So I assume that you are referring to unmanaged executables. There is no officially supported way to create an unmanaged process from a file held in memory. The only supported way to do this is to write it to a file and use, CreateProcess or similar.

Having said that, if you are prepared to break the rules, there are plenty of libraries and code samples around that will trick Windows into creating a process from an executable image held in memory. Do be prepared for anti-malware programs to take an interest in your program once it starts doing this.

Initialize a byte array to a certain value, other than the default null?

For small arrays use array initialisation syntax:

var sevenItems = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };

For larger arrays use a standard for loop. This is the most readable and efficient way to do it:

var sevenThousandItems = new byte[7000];
for (int i = 0; i < sevenThousandItems.Length; i++)
{
sevenThousandItems[i] = 0x20;
}

Of course, if you need to do this a lot then you could create a helper method to help keep your code concise:

byte[] sevenItems = CreateSpecialByteArray(7);
byte[] sevenThousandItems = CreateSpecialByteArray(7000);

// ...

public static byte[] CreateSpecialByteArray(int length)
{
var arr = new byte[length];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = 0x20;
}
return arr;
}


Related Topics



Leave a reply



Submit