Forum Discussion
tylermontney_acc
Feb 16, 2022Brass Contributor
ResourceReader prepends 4 bytes when debugger is attached
Edit
Today discovered my workaround isn't always working. I've tested using ResourceWriter then immediately using ResourceReader, and confirmed there's extra padding. (So that rules out CodeDomProvider.CompileAssemblyFromSource.) Below is my new workaround.
Setting
using (var rw = new ResourceWriter(resPath))
{
for(int i = 0; i < resName.Length; i++)
{
string n = resName[i];
string nl = resName[i] + "Length";
byte[] o = ToByteArray(data[i]);
if (o.GetType() == typeof(string))
{
rw.AddResource(n, o);
}
else
{
rw.AddResourceData(n, "ResourceTypeCode.ByteArray", o);
}
rw.AddResource(nl, o.Length); // Needed to reliably determine length (see GetResource)
}
}
Getting
using (var rr = new ResourceReader(stream))
{
string dataType = null;
byte[] data = null;
string dataLengthType = null;
byte[] bDataLength = null;
int dataLength = -1;
try
{
rr.GetResourceData(resName, out dataType, out data);
rr.GetResourceData(resName + "Length", out dataLengthType, out bDataLength);
dataLength = BitConverter.ToInt32(bDataLength, 0);
}
catch (Exception)
{
continue;
}
if (data.Length != dataLength)
{
int offset = data.Length - dataLength;
byte[] data2 = new byte[data.Length - offset];
Array.Copy(data, offset, data2, 0, data2.Length);
return data2;
}
else
{
return data;
}
}
Original
I'm building something that uses CodeDomProvider.CompileAssemblyFromSource to build a self-contained installer, which includes resources. If I'm running from the debugger, I have to remove the first 4 bytes (e.g. corrupts JSON). If I'm running from binary (outside VS), it's fine. The first 4 bytes can be, from what I remember:
- NUL: ASCII (0)
- EOT: ASCII (3 or 4?)
- ®: ANSI (174)
Here's a snippet of how I have to work around it:
using (var rr = new ResourceReader(stream))
{
string dataType = null;
byte[] data = null;
try
{
rr.GetResourceData(resName, out dataType, out data);
}
catch (Exception)
{
continue;
}
if (Debugger.IsAttached)
{
byte[] data2 = new byte[data.Length - 4];
Array.Copy(data, 4, data2, 0, data2.Length);
return data2;
}
else
{
return data;
}
}
Has anyone seen this? I'm targeting .NET framework 4.7.2.
- tylermontney_accBrass ContributorFinally found someone else who noticed this: https://stackoverflow.com/questions/32891004/why-resourcereader-getresourcedata-return-data-of-type-resourcetypecode-stream