Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to create a "Array of Bytes" in VBScript?

11,134 views
Skip to first unread message

Arno Bosch

unread,
May 23, 2005, 10:42:11 AM5/23/05
to
Hello everybody out there,

I need to create an "array of bytes" in VBScript. If I try something like:
===
dim Test5()
for j=0 to 10
redim preserve Test5(j)
Test5(j) = CByte(j)
next
===
Result:
Though: vartype(Test5(1)) = 17 = Byte
there is: vartype(Test5) = 8204 = array of variant

Has anybody an idea how to create the correct data type?

Thanks a lot
Arno

Richard Mueller [MVP]

unread,
May 23, 2005, 1:30:28 PM5/23/05
to
Arno Bosch wrote:

> I need to create an "array of bytes" in VBScript. If I try something like:
> ===
> dim Test5()
> for j=0 to 10
> redim preserve Test5(j)
> Test5(j) = CByte(j)
> next
> ===
> Result:
> Though: vartype(Test5(1)) = 17 = Byte
> there is: vartype(Test5) = 8204 = array of variant
>
> Has anybody an idea how to create the correct data type?

Hi,

As you've found, you can create an array of byte values, but the datatype
for the array is variant. You cannot create a variable of datatype Byte()
(byte array) in VBScript (although you can read a byte array). You can only
create or modify a byte array in VB, where you can Dim it as Byte().

--
Richard
Microsoft MVP Scripting and ADSI
Hilltop Lab web site - http://www.rlmueller.net
--


Michael Harris (MVP)

unread,
May 23, 2005, 8:09:40 PM5/23/05
to
>> Has anybody an idea how to create the correct data type?
>
> Hi,
>
> As you've found, you can create an array of byte values, but the
> datatype for the array is variant. You cannot create a variable of
> datatype Byte() (byte array) in VBScript (although you can read a
> byte array). You can only create or modify a byte array in VB, where
> you can Dim it as Byte().


It *is* possible to create a "Byte()" via an ADODB.Stream object...

'====
' How to create a true Byte Array in VBScript.
' A true Byte Array will have Typename() -> "Byte()"
'====

Const adTypeBinary = 1
Const adTypeText = 2
Const adSaveCreateOverWrite = 2

set fso = createobject("scripting.filesystemobject")
set stream = createobject("adodb.stream")
temp = fso.gettempname()

stream.type = adTypeText
stream.charset = "ASCII"
stream.open

'here you would loop over your binary source string
'with lenb(),midb(),ascb(),chrb() functions...
'
'this demo loop from 0 to 255 just proves that
'stream.writetext is OK with any binary character value...
'
for i = 0 to 255
wscript.echo i,chr(i)
stream.writetext chr(i)
next

stream.savetofile temp, adSaveCreateOverWrite
stream.close

stream.type = adTypeBinary

stream.open
stream.loadfromfile temp
trueByteArray = stream.read
stream.close
fso.deletefile temp
msgbox "typename(trueByteArray) -> " & typename(trueByteArray)
msgbox ByteArrayToHexString(trueByteArray)

wscript.quit

Function ByteArrayToHexString(bytearray)
Dim I
Redim B(lenb(bytearray)-1)

For I=1 to lenb(bytearray)
B(I-1) = right("0" & hex(AscB(MidB(bytearray,I,1))),2)
Next
ByteArrayToHexString = Join(B,",")

End Function

--
Michael Harris
Microsoft MVP Scripting
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Please ask follow-up questions via the original newsgroup thread.

Richard Mueller [MVP]

unread,
May 23, 2005, 9:44:01 PM5/23/05
to

Hi,

I just saw and replied to your similar post in the server.scripting
newsgroup. Since then I have confirmed that using the Stream object does
create a variable of type Byte(), I can assign any binary values I desire,
and I can assign this byte array to the logonHours attribute of a user
object, as exposed by the LDAP provider (and presumably, the loginHours
attribute exposed by WinNT). Up until now I have believed that this could
only be done in VB. I must have missed assigning stream.type in the past. I
assume adTypeBinary = 1.

However, it gets tricky, because the bytes seem to be written in "reverse"
order. For example, when I assign hex FC, which is binary "11111100", the
corresponding logon hours are "11001111", which is hex CF. Similar to
working in assembly language.

Arno Bosch

unread,
May 24, 2005, 5:26:04 AM5/24/05
to
Hi Richard,

I tried Michaels example code and had good results for chr(i) where
0<=i<=127 but it did not work for 128<=i<=255 at all.

You have to change the line "Stream.Charset = "ASCII"" to "Stream.Charset =
"windows-1252"" for making it work for 0<=i<=255.

So this code should work for my problem even though it is a detour when I
first have to create a file and then can import it as a byte-array.

Anyway I get the correct data-type (8209=array of byte). Thats what I wanted!

Thanks a lot to both of you for your help!

Arno

Miyahn

unread,
May 24, 2005, 9:12:42 AM5/24/05
to
"Arno Bosch" wrote in message news:797EE731-4F86-4882...@microsoft.com

> So this code should work for my problem even though it is a detour when I
> first have to create a file and then can import it as a byte-array.

You can copy data from a text stream to a binary stream, so you can get
a array of bytes without creating a temporary file.

The following script demonstrate this method.

' FileName: BinHandle.vbs
Const Path = "%userprofile%\My Documents\TestData.xls"
Dim Buffer, FileName
FileName = CreateObject("WScript.Shell").ExpandEnvironmentStrings(Path)
' Read Excel file to an array of variants.
Buffer = ReadBinary(FileName)
' Convert the array of variants to an array of bytes & overwrite to file.
WriteBinary FileName, Buffer
MsgBox "A test was completed."
'
Function ReadBinary(FileName)
Dim Buf(), I
With CreateObject("ADODB.Stream")
.Mode = 3: .Type = 1: .Open: .LoadFromFile FileName
ReDim Buf(.Size - 1)
For I = 0 To .Size - 1: Buf(I) = AscB(.Read(1)): Next
.Close
End With
ReadBinary = Buf
End Function
'
Sub WriteBinary(FileName, Buf)
Dim aBuf, aStream
aBuf = BuildString(Buf)
Set aStream = CreateObject("ADODB.Stream")
aStream.Type = 1: aStream.Open
With CreateObject("ADODB.Stream")
.Type = 2: .Open: .WriteText aBuf
' Copy data from a text stream to a binary stream.
' (skip Unicode mark? :FFFE)
.Position = 2: .CopyTo aStream, UBound(Buf) + 1: .Close
End With
' At this point aStream.Read give an array of bytes.
aStream.SaveToFile FileName, 2: aStream.Close
Set aStream = Nothing
End Sub
'
Function BuildString(Buf)
Dim I, aBuf(), Size
Size = UBound(Buf): ReDim aBuf(Size \ 2)
For I = 0 To Size - 1 Step 2
aBuf(I \ 2) = ChrW(Buf(I + 1) * 256 + Buf(I))
Next
If I = Size Then aBuf(I \ 2) = ChrW(Buf(I))
BuildString = Join(aBuf, "")
End Function

--
Miyahn (Masataka Miyashita) JPN
Microsoft MVP for Microsoft Office - Excel(Jan 2005 - Dec 2005)
HQF0...@nifty.ne.jp

mr_unreliable

unread,
May 24, 2005, 11:27:47 AM5/24/05
to

hi Richard (MVP),

As an MVP, I'm sure that you know that Intel x86 machines are
"Little Endian". There are plenty of explanations of this to
be found on the web, but in plain English: the bytes in memory
do not appear in the same order as they do when fetched into
a register (as an integer, or a as long) -- or, vice-versa.

If that little detail has passed out of your consciousness,
then that may explain the "reverse order" effect you are
experiencing.

cheers, jw

Bob Barrows [MVP]

unread,
May 24, 2005, 11:31:46 AM5/24/05
to
mr_unreliable wrote:
> hi Richard (MVP),
>
> As an MVP, I'm sure that you know

"MVP" is not equivalent to "expert in all computer-related issues". An MVP
is awarded because of the amount of help a person provides to the community,
as well as the appropriateness of the help provided.

Bob Barrows
--
Microsoft MVP -- ASP/ASP.NET
Please reply to the newsgroup. The email account listed in my From
header is my spam trap, so I don't check it very often. You will get a
quicker response by posting to the newsgroup.


McKirahan

unread,
May 25, 2005, 6:12:13 AM5/25/05
to
"Bob Barrows [MVP]" <reb0...@NOyahoo.SPAMcom> wrote in message
news:uFxkzWHY...@TK2MSFTNGP10.phx.gbl...

> mr_unreliable wrote:
> > hi Richard (MVP),
> >
> > As an MVP, I'm sure that you know
>
> "MVP" is not equivalent to "expert in all computer-related issues". An MVP
> is awarded because of the amount of help a person provides to the
community,
> as well as the appropriateness of the help provided.
>
> Bob Barrows
> --
> Microsoft MVP -- ASP/ASP.NET


I didn't know that. I thought MVP was the new MCP title.


mayayana

unread,
May 25, 2005, 10:19:19 AM5/25/05
to
You didn't mention what you need this for, but
you can do anything binary with Textstream. You
don't need ADODB and in many cases you
don't need conversion to bytes. A Textstream string
is binary until you look at it (quantum Textstream?).
Since VBS uses Chr(0) to demarcate string ends,
if you try to get the length of the string you'll get
the offset of the first Chr(0). If you try to use ReadAll
you'll only read up to the first Chr(0). Aside from those
limitations, you can read and write binary as Textstrream
strings.

If you use:

A1 = Array(1, 0, 100, 200, 255, 10)

you'll get a variant array. But those values can
be written to a string:

For i = 0 to UBound(A1)
s = s & Chr(A1(i))
Next

....and the string can be written to disk as binary.

For an example that reads and writes binary, also
using arrays to set up binary data, see here:

http://www.jsware.net/jsware/jsware/scripts.html#iconextr

It's a script that uses only Textstream to read from
any PE file that contains icons. It parses the resource
table, extracts the icon bytes, writes binary file headers
for each icon by using the array method above, then writes the
icons to disk. It may seem a bit sloppy to use Textstream for
that but it works, and on my Win98 1660 Athlon it extracts
and writes 350-odd icons from Shell32.dll almost instantly.
(It also avoids the version limitation associated with using
ADODB if the target computer doesn't have the version
with the Stream object - 2.6+, I think.)

--
--
Arno Bosch <Arno...@discussions.microsoft.com> wrote in message
news:797EE731-4F86-4882...@microsoft.com...

Richard Mueller [MVP]

unread,
May 26, 2005, 12:14:00 PM5/26/05
to
Hi,

The problem is that some Active Directory attributes, like logonHours, are
byte arrays. AD will not allow you to assign a variant array or binary
string to logonHours. Byte arrays can be read and handled in VBScript (with
effort), but you cannot declare or create a variable of datatype byte().
Fortunately, VBScript can read byte arrays from AD or the ADODB.Stream
object. ADO allows you to write bytes to the stream and ADO does the
conversion.

--
Richard
Microsoft MVP Scripting and ADSI
Hilltop Lab web site - http://www.rlmueller.net
--

"mayayana" <mayaXX...@mindYYspring.com> wrote in message
news:HP%ke.7597$M36....@newsread1.news.atl.earthlink.net...

Bob Barrows [MVP]

unread,
May 26, 2005, 1:26:02 PM5/26/05
to
McKirahan wrote:
> "Bob Barrows [MVP]" <reb0...@NOyahoo.SPAMcom> wrote in message
> news:uFxkzWHY...@TK2MSFTNGP10.phx.gbl...
>> mr_unreliable wrote:
>>> hi Richard (MVP),
>>>
>>> As an MVP, I'm sure that you know
>>
>> "MVP" is not equivalent to "expert in all computer-related issues".
>> An MVP is awarded because of the amount of help a person provides to
>> the community, as well as the appropriateness of the help provided.
>>
>
> I didn't know that. I thought MVP was the new MCP title.

http://mvp.support.microsoft.com/


--
Microsoft MVP -- ASP/ASP.NET

Fred Xiong (疯狂小瑞瑞)

unread,
Jul 24, 2023, 6:25:52 PM7/24/23
to
If you just right want to fetch data with createObject("Microsoft.XMLHTTP"), the responseBody property returns a byte() and that is what you want.
Dim h As New MSXML2.XMLHTTP
h.open "GET", "https://127.0.0.1:81/file.zip", False
h.send
Dim a As New ADODB.Stream
a.Type = adTypeBinary ' Const adTypeBinary = 1
a.open
a.Position = 0 ' for if some one want to setHttpHeader range:
a.Write h.responseBody
a.saveToFile "D:\file2.zip", adSaveCreateOverWrite ' Const adSaveCreateOverWrite = 2
a.Close
0 new messages