Search code examples
htmltestingvbscripthta

Why do I get a "necessary object" error on objShell?


I don't know why I'm getting an error on the Set objShell = statement of this VBS code (it's in an HTML). I'm working on a .HTA launcher for a game named Doom and this VBScript serves to select the game and launch it with some parameters.

Dim pwad, warp, skill, execDoom, execPwad, execWarp, execSkill, rep, fso, file, OpFScript, WScript, objShell
Set objShell = WScript.CreateObject("WScript.Shell")
Set pwad = document.GetElementById("inpFILE")
Set warp = document.GetElementById("inpMAP")
Set skill = document.GetElementById("inpSKILL")

Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.OpenTextFile("C:\ZDLRemastered\launcher\ScriptOpFile.txt", 1)
OpFScript = file.ReadAll

Function GetFileDlgEx(sIniDir,sFilter,sTitle) 
    Set oDlg = CreateObject("WScript.Shell").Exec("mshta.exe & OpFScript")
    oDlg.StdIn.Write "var iniDir='" & sIniDir & "';var filter='" & sFilter & "';var title='" & sTitle & "';" 
    GetFileDlgEx = oDlg.StdOut.ReadAll 
End Function

sFilter = "Doom Archive (*.wad)|*.wad|"  
sTitle = "Select a Doom IWAD"
rep = GetFileDlgEx(Replace(sIniDir,"\","\\"),sFilter,sTitle)

execDoom = "C:\ZDLRemastered\gzdoom\gzdoom.exe -config C:\ZDLRemastered\gzdoom\gzconfig.ini -iwad "
execPwad = " -file "
execWarp = " -warp "
execSkill = " -skill "
objShell.Run execDoom & Chr(34) & rep & Chr(34) & execPwad & Chr(34) & pwad & Chr(34) & execWarp & Chr(34) & warp & Chr(34) & execSkill & Chr(34) & skill & Chr(34)

This is the error:

necessary object: " -


Solution

  • HTAs run in a different engine than regular VBScript (mshta.exe vs wscript.exe/cscript.exe). The HTA engine does not provide an intrinsic WScript object, hence WScript.CreateObject() or WScript.Sleep() or WScript.Quit() won't work.

    That intrinsic object isn't required for creating objects, though, since VBScript also has a global function CreateObject() (which is not the same as WScript.CreateObject()).

    Change this:

    Set objShell = WScript.CreateObject("WScript.Shell")
    

    into this:

    Set objShell = CreateObject("WScript.Shell")
    

    and the problem will disappear.