ResourceReader prepends 4 bytes when debugger is attached

%3CLINGO-SUB%20id%3D%22lingo-sub-3176238%22%20slang%3D%22en-US%22%3EResourceReader%20prepends%204%20bytes%20when%20debugger%20is%20attached%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-3176238%22%20slang%3D%22en-US%22%3E%3CP%3EI'm%20building%20something%20that%20uses%20%3CEM%3ECodeDomProvider.CompileAssemblyFromSource%3C%2FEM%3E%20to%20build%20a%20self-contained%20installer%2C%20which%20includes%20resources.%20If%20I'm%20running%20from%20the%20debugger%2C%20I%20have%20to%20remove%20the%20first%204%20bytes%20(e.g.%20corrupts%20JSON).%20If%20I'm%20running%20from%20binary%20(outside%20VS)%2C%20it's%20fine.%20The%20first%204%20bytes%20can%20be%2C%20from%20what%20I%20remember%3A%3C%2FP%3E%3CUL%3E%3CLI%3ENUL%3A%20ASCII%20(0)%3C%2FLI%3E%3CLI%3EEOT%3A%20ASCII%20(3%20or%204%3F)%3C%2FLI%3E%3CLI%3E%26amp%3Breg%3A%20ANSI%20(174)%3C%2FLI%3E%3C%2FUL%3E%3CP%3EHere's%20a%20snippet%20of%20how%20I%20have%20to%20work%20around%20it%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-csharp%22%3E%3CCODE%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20using%20(var%20rr%20%3D%20new%20ResourceReader(stream))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20string%20dataType%20%3D%20null%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20byte%5B%5D%20data%20%3D%20null%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rr.GetResourceData(resName%2C%20out%20dataType%2C%20out%20data)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20catch%20(Exception)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(Debugger.IsAttached)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20byte%5B%5D%20data2%20%3D%20new%20byte%5Bdata.Length%20-%204%5D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Array.Copy(data%2C%204%2C%20data2%2C%200%2C%20data2.Length)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20data2%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20else%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20data%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EHas%20anyone%20seen%20this%3F%20I'm%20targeting%20.NET%20framework%204.7.2.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-3176238%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EConsole%20Apps%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
New Contributor

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?)
  • &reg: 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.

1 Reply