Home > Software engineering >  Why is StreamWriter adding random bytes to a file?
Why is StreamWriter adding random bytes to a file?

Time:05-25

I'm trying to translate a virtual key code with ToAsciiEx() and write it to a debug file. For some reason, the output file contains a load of random trash bytes interspersed with the key codes I want to log.

I'm importing ToAsciiEx() like this:

[DllImport("user32.dll")]
static extern int ToAsciiEx(uint uVirtKey, uint uScanCode, byte[] lpKeyState, [Out] StringBuilder lpChar, uint uFlags, IntPtr hkl);

And the code:

byte[] state = new byte[256];
GetKeyboardState(state);
        
StringBuilder s = new StringBuilder(new String('\0', 32), 32);
int ret = ToAsciiEx((uint)vkCode, 0, state, s, 0, IntPtr.Zero);
        
string k = "";
if (ret == 1 && s.Length > 0)
{
    k = s.ToString();
}
        
var logFile = "DebugLog.txt";
var logPath = Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%")   "\\"   logFile;
using (StreamWriter sw = new StreamWriter(logPath, true))
{
    sw.Write(k);
}

Passing the virtual key codes for 'Test', I get this: TSÕà[Õ-ÕØé¿eê¿sê¿tê¿

Could this be an encoding issue? Or is ToAsciiEx() not writing a null-terminator perhaps?

Thanks!

CodePudding user response:

The return value from ToAsciiEx tells you how many characters were copied to the output, but you never use that information to trim the StringBuilder.

The Windows API has no idea what a .NET StringBuilder class is, and doesn't change its length. It's writing data into a memory space that was prepared for it by the magic of p/invoke.... and then p/invoke copies the contents into the StringBuilder. But s still has the length it was created with.

Try k = s.ToString(0, ret);

  •  Tags:  
  • c#
  • Related