1

I am trying to read a binary file and edit the data and then write the file back as a new file. Reading the file, and Writing the file is not a problem... it works fine.

But, any way I try to modify the binary data, I get an error: "VBScript runtime error: Type mismatch"

As an example, I am reading a file and modifying the 3rd byte to be an "@" (at-sign).

Option Explicit

Const ADTYPEBINARY = 1
Const ADSAVECREATEOVERWRITE = 2

Dim gstrInputFileName 
Dim gstrOutputFileName 
Dim gobjBinaryInputStream
Dim gobjBinaryOutputStream
Dim gbytearrayReadBinaryFile

    gstrInputFileName =  "some-binary-file.bin"
    gstrOutputFileName = "output-binary-filename.bin"

WScript.Echo "Reading the file data"
    Set gobjBinaryInputStream = CreateObject("ADODB.Stream")
    gobjBinaryInputStream.Type = ADTYPEBINARY
    gobjBinaryInputStream.Open
    gobjBinaryInputStream.LoadFromFile gstrInputFileName
    gbytearrayReadBinaryFile = gobjBinaryInputStream.Read
    gobjBinaryInputStream.Close
    Set gobjBinaryInputStream = Nothing


WScript.Echo "Modifying the file data"
'   These all fail... "Type mismatch"
 '' pwwqbytearrayReadBinaryFile(3) = &H40
 '' pwwqbytearrayReadBinaryFile(3) = ChrB(65)
 '' pwwqbytearrayReadBinaryFile(3) = Chr(65)
 '' pwwqbytearrayReadBinaryFile(3) = AscB("@")
 '' pwwqbytearrayReadBinaryFile(3) = Asc("@")
 '' pwwqbytearrayReadBinaryFile(3) = "@"
 '' pwwqbytearrayReadBinaryFile(3) = 65


WScript.Echo "Writing the file data"
    Set gobjBinaryOutputStream = CreateObject("ADODB.Stream")
    gobjBinaryOutputStream.Type = ADTYPEBINARY
    gobjBinaryOutputStream.Open
    gobjBinaryOutputStream.Write gbytearrayReadBinaryFile
    gobjBinaryOutputStream.SaveToFile gstrOutputFileName, ADSAVECREATEOVERWRITE
    gobjBinaryOutputStream.Close
    Set gobjBinaryOutputStream = Nothing

WScript.Echo 
WScript.Quit
Kevin Fegan
  • 1,292
  • 1
  • 16
  • 29

1 Answers1

2

The problem is: binary streams deliver and expect byte arrays (TypeName "Byte()", VarType 8209) which can't be manipulated with VBScript. A solution for your sample task is:

' read first byte from input, write it to output
gobjBinaryOutputStream.Write gobjBinaryInputStream.Read(1)
' skip second byte from input
gobjBinaryInputStream.Position = gobjBinaryInputStream.Position + 1
' use .NET to get a byte array containing '@' and write it to output
gobjBinaryOutputStream.Write CreateObject("System.Text.ASCIIEncoding").GetBytes_4("@")
' copy rest of input to output
gobjBinaryOutputStream.Write gobjBinaryInputStream.Read

Obviously, this approach does not scale for real world tasks; so you should consider using a language that supports binary data natively.

Ekkehard.Horner
  • 38,498
  • 2
  • 45
  • 96
  • I need this for scripted editing of small Binary files located on my computer, in the range of 500-Bytes to 5KB (but typically less than 1KB), so I think your solution should work nicely. My code showing replacement of a character with an "@" was only an example... this could be any byte value from &h00 to &Hff. So, would I use something like "...).GetBytes_4(Chr(0))" or "...).GetBytes_4(ChrB(0))" ? – Kevin Fegan Jul 26 '12 at 21:23
  • @KevinFegan GetBytes_4() expects a string, so ChrB() is wrong; you should check the docs/test carefully whether GetBytes_4(ChrW(n)) returns an one-element byte array containing n for *all* n in 0 .. 255. – Ekkehard.Horner Jul 26 '12 at 21:42
  • I have tried to search (Google) for online docs on "System.Text.ASCIIEncoding" and "GetBytes_4" without success. Can you refer me to online docs regarding these? – Kevin Fegan Jul 27 '12 at 15:40
  • Start with http://msdn.microsoft.com/en-us/library/system.text.asciiencoding.aspx; numerical suffices are VBScript's way to deal with methods having the same name, but different parameter lists. (spoiler: *ASCII*encoding fails for n > 127) – Ekkehard.Horner Jul 27 '12 at 16:02