Jump to content

Subscript Out of Range


Recommended Posts

I am working getting the (unreleased) ImageX COM Based HTA v9.1 working. v7 and v9 can be found here:

http://www.msfn.org/board/index.php?showtopic=133547

Version 9.1 was sent to me from Geezery prior to killing the availability of version 9.0. It adds (at least) two functions, one of which allows a custom Diskpart script option, and also the ability to display the Image Index value in the name. I am testing migration to this version now, and after testing I can make it available in that thread. But it is having difficulty parsing the HTA for display. I haven't even tested actually using it yet.

I am receiving the following Script Error:

Line: 236

Char: 3

Error: Subscript out of range: 'i'

Code: 0

I understand what this error means, but the general VBS examples that websites give me aren't enough for me to figure out why. The error points to this Subroutine, the line in question prefixed with '--->' (added only for this post) so if you copypasta this, make sure to remove the arrow.

Sub parseFile()

Dim objTextFile, sReadLine, pos, pos2, pos3, i, tmpStr1, oExec, objSel1, strFile, objSel2, SysFolder2,temppiFile
Set objSel1 = window.document.getElementById("select1")

Set SysFolder2 = Objfso.GetSpecialFolder(1)
temppiFile = SysFolder2 & "\temp.txt"

strFile = myFilepath + objSel1.options(objSel1.selectedindex).text
ObjShell.Run "%comspec% /c Imagex /info "+strFile+" > "+temppifile,0,True
i = -1
Redim strNames(0)
Redim strIndx(0)
Redim strDesc(0)

If objFso.FileExists(temppifile) Then
Set objTextFile = objFso.OpenTextFile(temppifile, 1)
Do While Not objTextFile.AtEndOfStream
sReadLine = objTextFile.ReadLine
pos = Instr(1, sReadLine, "<NAME>", 1)
pos2 = Instr(1, sReadLine, "<IMAGE>", 1)
pos3 = Instr(1, sReadLine, "<DESCRIPTION>", 1)
If pos2 > 0 Then
i = i + 1
Redim Preserve strIndx(i)
Redim Preserve strNames(i)
Redim Preserve strDesc(i)
strDesc(i) = "NO DESCRIPTION"
tmpStr1 = Right(sReadLine, Len(sReadLine) - (pos2 + 13))
strIndx(i) = Left(tmpStr1, Len(tmpStr1) -3)

End If
If pos > 0 Then
tmpStr1 = Right(sReadLine, Len(sReadLine) - (pos + 5))
strNames(i) = Left(tmpStr1, Len(tmpStr1) -8)
End If
If pos3 > 0 Then
---> tmpStr1 = Right(sReadLine, Len(sReadLine) - (pos3 + 12))
strDesc(i) = Left(tmpStr1, Len(tmpStr1) -15)
End If
Loop
End If
enumDirs
End sub

I looked it over and for any syntax errors but nothing stood out to me. I'm thinking possible requirements to clear the var before reuse, but I don't know VBScript well enough to know how to begin. So anyone can take a look at this and see if anything stands out.

Link to comment
Share on other sites


It appears to be a logic error. i is assigned the value -1 to start, and is only increased if the "if pos2 > 0 then" block. If the "if pos3 > 0" block is executed without the "if pos2 > 0 then" block, then the line after what you marked will produce the error since the subscript would be invalid (-1) in most cases.

I don't know if that helps fully, but hopefully it'll give you a pointer towards how to solve it.

Edited by Glenn9999
Link to comment
Share on other sites

Try this, it should be bullet proof:

Sub parseFile()

Dim objTextFile, sReadLine, pos, pos2, pos3, i, tmpStr1, oExec, objSel1, strFile, objSel2, SysFolder2,temppiFile
Set objSel1 = window.document.getElementById("select1")

Set SysFolder2 = Objfso.GetSpecialFolder(1)
temppiFile = SysFolder2 & "\temp.txt"

strFile = myFilepath + objSel1.options(objSel1.selectedindex).text
ObjShell.Run "%comspec% /c Imagex /info "+strFile+" > "+temppifile,0,True
i = -1
Redim strNames(0)
Redim strIndx(0)
Redim strDesc(0)

If objFso.FileExists(temppifile) Then
Set objTextFile = objFso.OpenTextFile(temppifile, 1)
Do Until objTextFile.AtEndOfStream
sReadLine = objTextFile.ReadLine
pos = Instr(1, sReadLine, "<NAME>", 1)
pos2 = Instr(1, sReadLine, "<IMAGE>", 1)
pos3 = Instr(1, sReadLine, "<DESCRIPTION>", 1)
If pos2 > 0 Then
i=i+1
Redim Preserve strIndx(i)
Redim Preserve strNames(i)
Redim Preserve strDesc(i)
strDesc(i) = "NO DESCRIPTION"
If Len(sReadLine) > pos + 13 Then
tmpStr1 = Right(sReadLine, Len(sReadLine) - pos2 -13)
If Len(tmpStr1) > 3 Then
strIndx(i) = Left(tmpStr1, Len(tmpStr1) -3)
End If
End If
If pos > 0 And Len(sReadLine) > pos + 5 Then
tmpStr1 = Right(sReadLine, Len(sReadLine) - pos -5)
If Len(tmpStr1) > 8 Then
strNames(i) = Left(tmpStr1, Len(tmpStr1) -8)
End If
End If
If pos3 > 0 And Len(sReadLine) > pos3 + 12 Then '---Here was the error
tmpStr1 = Right(sReadLine, Len(sReadLine) - pos3 -12)
If Len(tmpStr1) > 15 Then
strDesc(i) = Left(tmpStr1, Len(tmpStr1) -15)
End If
End If
End If
Loop
End If
enumDirs
End sub

Edited by Fredledingue
Link to comment
Share on other sites

Here is the code cleaned-up

Sub parseFile()
Dim ts, t, pos, pos2, pos3, i, tmp1, oExec, objSel1, temppiFile
Set objSel1 = window.document.getElementById("select1")
temppiFile = Objfso.GetSpecialFolder(1) & "\temp.txt"
ObjShell.Run "%comspec% /c Imagex /info " _
& myFilepath & objSel1.options(objSel1.selectedindex).text _
& " > " & temppifile, 0, True
i=-1
Redim Names(0)
Redim Indx(0)
Redim Desc(0)
If objFso.FileExists(temppifile) Then
Set ts = objFso.OpenTextFile(temppifile, 1)
Do Until ts.AtEndOfStream
t = ts.ReadLine
pos = InStr(1, t, "<NAME>", 1)
pos2 = InStr(1, t, "<IMAGE>", 1)
pos3 = InStr(1, t, "<DESCRIPTION>", 1)
If pos2 > 0 Then
i=i+1
Redim Preserve Indx(i)
Redim Preserve Names(i)
Redim Preserve Desc(i)
Desc(i) = "NO DESCRIPTION"
If Len(t) > pos + 13 Then
tmp1 = Right(t, Len(t) - pos2 -13)
If Len(tmp1) > 3 Then
Indx(i) = Left(tmp1, Len(tmp1) -3)
End If
End If
If pos > 0 And Len(t) > pos + 5 Then
tmp1 = Right(t, Len(t) - pos -5)
If Len(tmp1) > 8 Then
Names(i) = Left(tmp1, Len(tmp1) -8)
End If
End If
If pos3 > 0 And Len(t) > pos3 + 12 Then '---Here was the error
tmp1 = Right(t, Len(t) - pos3 -12)
If Len(tmp1) > 15 Then
Desc(i) = Left(tmp1, Len(tmp1) -15)
End If
End If
End If
Loop
End If
enumDirs
End sub

Edited by Fredledingue
Link to comment
Share on other sites

It definately didn't like that peice. I used the cleaned up part. It says Syntax Error on line 214, which is this one:

		pos = In(1, t, "<NAME>", 1)

BTW I will credit you in the source code if we can get this working.

Link to comment
Share on other sites

I have looked at the full source code.

If you want I can correct and clean up redundancies and other stuffs.

I already replaced all the "& Chr(34) &" by ""....

My version here:

http://www.hageart.com/vbs/ImageX.zip

Edit:

There is a problem with this script: It writes a hta file with only one variable different in the whole hta script (CMDpartHD).

It would be better to:

1/ create the script of this hta in 2 separate files: one file with the code until "CMDpartHD" and the second from "CMDpartHD" and then read the two files and join them to create the hta

or still better:

2/ have a single hta and transfer the variable "CMDpartHD" via command line parameter.

Edited by Fredledingue
Link to comment
Share on other sites

I am wondering where you got the full source for version 9.1? Only verson 9, the one in my post, it available as far as I know.

Edit: OK the page renders now, but it won't show the different images in each WIM. So something is different. All that should be different for this subroutine and the one in version 9.0, is that it should show the Image Index number parsed from the XML in IMAGEX /INFO next to the DESCRIPTION, which should be next to the radio button.

Link to comment
Share on other sites

Yeah, that's the v9.0. Geezery sent me a v9.1 version, which is what I am working on. You can post your cleaned up code in that thread and I will update the post later.

As far as getting the image index to work with this sub, I can tell you that it is creating the txt files and running the imagex /info command. But it is not displaying the names of the images inside the WIMs when you select them. Perhaps that isn't handled in this sub?

Link to comment
Share on other sites

Yes, see it calls EnumDirs at the end, which is what is supposed to show that on the screen. Here is that portion, or look at that in the code you changed.

Sub enumDirs
Dim colFilelist, objFile, strButtons, objShortcut, colTargetList, objTarget, x, y, strKey, strItem, k, mxChk, tmpstr1
ReDim arrButtons(1,-1)
Call VolInfo(tmpstr1)
strBody = ""
mxChk = ""
strTaskValue = "1"
For k = 0 To Ubound(strIndx)
ReDim Preserve arrButtons(1,UBound(arrButtons,2)+1)
arrButtons(0,UBound(arrButtons,2)) = strNames(k)
arrButtons(1,UBound(arrButtons,2)) = "<Input type=radio name=radioList id='" & strIndx(k) & "' onClick=showRadioInfo>" & strNames(k) & " - (Index: " & strIndx(k) & ")</BUTTON><BR>"
Next
'Perform a a shell sort of the string array based on button label
For x = 0 To UBound(arrButtons,2) - 1
For y = x To UBound(arrButtons,2)
If StrComp(arrButtons(0,x),arrButtons(0,y),vbTextCompare) > 0 Then
strKey = arrButtons(0,x)
strItem = arrButtons(1,x)
arrButtons(0,x) = arrButtons(0,y)
arrButtons(1,x) = arrButtons(1,y)
arrButtons(0,y) = strKey
arrButtons(1,y) = strItem
End If
Next
Next

For x = 0 To UBound(arrButtons,2)
strButtons = strButtons & "<tr><td id=buttonTd>" & arrButtons(1,x) & "</td></tr>"
Next
strBody = strBody & "<BR><BR><b>Select Image to Apply:</b><BR><BR><HR><BR>"
body.innerHTML = strBody
strBody2 = "<BR><HR><BR><!--<button class='Btn' id=start title='Start Installing' Accesskey=S onclick=doTask(strTaskValue)><U>S</U>tart installing</BUTTON>--><BR><BR><BR>"
wimlist.innerHTML = strButtons
wimlist.style.visibility = "visible"
body2.innerHTML = strBody2
asemat.InnerHTML = "<div id='diskinfo'><BR>   <TABLE class='diskinfo'><B>Logical Disk Information:</b><BR><BR><P><tr><td><b><u>Drive</b></u></td><td align=center><b><u>Type</u></b></td><td align=center><b><u>FS</u></b></td><td align=center></td><td align=right><b><u>Used</u> / </b></td><td algin=left><b><u>Total </u></b></td></tr>" & tmpstr1 & "</TABLE></P></div>"
asemat.style.visibility = "visible"
End Sub

Link to comment
Share on other sites

Hi,

There were so many inconsistencies that I couldn't let this script like that so I spent some time cleaning it up.

I found indeed an obvious mistake in the EnumDirs sub.

Re-download the zip file and try.

There are 4 files. All 4 files must be in the same directory. This avoid rewriting hta and vbs again and again. And it frees up many many lines of code in the main hta.

The replaced the sub parseFile by the one we worked on on this thread.

The original sub has been renamed parseFileOri and is disabled.

On line 657 and 362 (of my version) there is "VARIABLE DOESN'T EXIST ELSEWHERE", it means that you should fix it.

(I didn't know what to do.)

HTH

Link to comment
Share on other sites

OK ha yes of course you found this other things, like launching the following programs:

1.exe

vista_pe_selector.exe

xp_pe_selector.exe

Those are my custom apps that I replaced those functions from the regular functions. The Append, Unmount and DoTask subs are in the original 9.0 source. I do not want the regular software people to have access to such things that would allow them to easily replace or erase the files on the server. So the PE_Selectors are apps that all for post-deployment installations of programs. The 1.exe does a drive remap to accomodate certain NICs which take too long to get an IP and when the drive mapping fails. Such as:

'------Remap1 Confirmation ***** CORRECT THIS *****
Sub Remap1
If window.confirm("Click OK to remap Network") Then
objshell.run("1"),0 '<--- Huh? ****
End If
End Sub
'-----------

1.exe has the following code (its in AutoIT)

; Program to workaround GImageX getting System Error 1231
RunWait( @ComSpec & " /c net use z: \\imagex.wds.local\images Password1 /user:remote" )
RunWait( @ComSpec & " /c net use v: \\vistaserver.wds.local\share Password1 /user:remote" )
Sleep( 1000 )
ProcessClose( "mshta.exe" )
Run( "mshta x:\windows\system32\ImageX.hta" )

I forgot that I had modified the Imagex.hta v9.1 version. :wacko:

I will try this out in a little bit.

Also, you noted "unmount" is not called anywhere. In my current HTA (v7.1) it has this in the tools section:

<input type="image" src="pics\unmount.png" title='Unmount Image' name="image" width="30" height="30" onclick=unmount()></input>

Edited by Tripredacus
Link to comment
Share on other sites

objshell.run("1"),0  '<--- Huh? ****

Ok I understand now. Running "1" looked a little bit wierd but it can be valid if 1.exe is registered.

Note that you shouldn't put parenthesis when the command doesn't return a variable.

objshell.run "1.exe" ,0

but you must type

errOut = objshell.run("1.exe"),0

Note that errOut is not the same as stdOut.

1.exe has the following code (its in AutoIT)

If this code is so simple, you can include it in VbScript.

 'Program to workaround GImageX getting System Error 1231
objShell.Run "%comspec% /c net use z: \\imagex.wds.local\images Password1 /user:remote", 0, True
objShell.Run "%comspec% /c net use v: \\vistaserver.wds.local\share Password1 /user:remote", 0, True
Sleep 1000
objShell.Run "mshta x:\windows\system32\ImageX.hta"
window.close

Also, you noted "unmount" is not called anywhere. In my current HTA (v7.1) it has this in the tools section:

So add the button in the hta form. ;)

Edited by Fredledingue
Link to comment
Share on other sites

You are right about the simplicity of the program. I am going through right now trying to upgrade our production server to use the v9.1 HTA. As I noted it currently uses the v7.1. I have a duplicate environment that I am testing in at the moment. Originally, 1.exe was called 'error1231.exe' and was only used from the cmd to fix a specific networking issue with Intel boards. I later added it to the button instead.

The use of it has depreciated, since I have worked around the issue by adding additional code in the startnet.cmd. So technically, we do not even use it anymore.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...