Projects Log

projects, diy

Search:

« PreviousNext »

Vbscript CGI (No… not ASP)

15 November 2007

Yesterday, I don't know how, but while doing nothing I suddenly got the best idea ever: Using vbscript scripts with apache… and guess what… after some coding/debugging hours, it actually works like a charm!

so how did I manage to get this working?
Each computer with at least "windows 2000" should have cscript.exe somewhere: it's the vbscript/jscript console interpreter

so I started to write my first script:

test.vbs
#!c:\WINDOWS\system32\cscript.exe
wscript.echo "Content-type: text/html" & vbcrlf
wscript.echo "Hello World"

but it didn't work (500 Internal Server Error) so I checked apache error log and found:
C:\\wamp\\cgi-bin\\test.vbs(1, 1) Erreur de compilation Microsoft VBScript: Instruction attendue\r

Error in the first line at the first character… oh wait that's the shebang
How to ignore the first line in my vbs code?

No idea? well that's the second best idea ever: you simply need to call another vbs script from the shebang that somehow ignores the first line and include the remaining part and call it for example "vbscript_cgi.vbs":

vbscript_cgi.vbs
Set arguments = WScript.Arguments
If arguments.Count >=1 Then
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists(arguments(0)) Then
Set cgi = FSO.OpenTextFile(arguments(0))
cgi.ReadLine
ExecuteGlobal cgi.ReadAll
cgi.Close
End If
Set FSO = Nothing
End If
Set arguments = Nothing

test.vbs
#!c:\WINDOWS\system32\cscript.exe "C:\wamp\cgi-bin\vbscript_cgi.vbs"
wscript.echo "Content-type: text/html" & vbcrlf
wscript.echo "Hello World"

Nah bad luck, still error 500… apache log says malformed header from script. Bad header=Microsoft (R) Windows Script H: test.vbs … wtf?!?

Oooh right… cscript always displays a banner when you launch a script:
C:\wamp\cgi-bin>cscript test.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. Tous droits réservés.

Lets add the "/nologo" switch in the shebang to avoid that:
test.vbs
#!c:\WINDOWS\system32\cscript.exe /nologo "C:\wamp\cgi-bin\vbscript_cgi.vbs"
wscript.echo "Content-type: text/html" & vbcrlf
wscript.echo "Hello World"

yayyyy it wooooooorks :D
hello world

after that I added some features such as the "print" alias, GET/POST variables support, and now that's a quick example what it can do:
advanced example

'''''''''''''''''''''''''''
'' vbscript_cgi.vbs ''
'' Kevin DEHLINGER ''
'' 2007 / dev.pulsed.net ''
'''''''''''''''''''''''''''

Set arguments = WScript.Arguments
If arguments.Count >=1 Then
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists(arguments(0)) Then
Set cgi = FSO.OpenTextFile(arguments(0))
cgi.ReadLine
ExecuteGlobal cgi.ReadAll
cgi.Close
End If
Set FSO = Nothing
End If
Set arguments = Nothing


sub print(v)
wscript.echo v
end sub

sub println(v)
wscript.echo v & vbcrlf
end sub


Function GetCgiVars

Set Shell = CreateObject( "WScript.Shell" )
reqmethod=Ucase( Shell.ExpandEnvironmentStrings("%REQUEST_METHOD%"))


Select Case reqmethod

Case "GET","HEAD"
cgiinput=Shell.ExpandEnvironmentStrings("%QUERY_STRING%")& ""

Case "POST"

content_length=Shell.ExpandEnvironmentStrings("%CONTENT_LENGTH%")

If not IsNumeric(content_length) then
print "Content-Type: text/plain" & vbcrlf
print "No Content-Length was sent with the POST request" & vbcrlf
Exit Function
End If

cgiinput= WScript.StdIn.ReadAll


Case Else
print "Content-Type: text/plain" & vbcrlf
print "Unsupported REQUEST_METHOD (" & reqmethod & ")" & vbcrlf
Exit Function

End Select

cgiinput=Replace(cgiinput,"+"," ")
cgiinput=Replace(cgiinput,"&",";")
cgiinput=Replace(cgiinput,"=","=;")

InputArray=Split(cgiinput,";")
Set CgiVars = CreateObject("Scripting.Dictionary")


status=0
Hash_Key=""

For Each value in InputArray
If(Mid(value,Len(value),1)="=") Then
Hash_Key=Mid(value,1,Len(value)-1)
Else
CgiVars.Add Unescape_Url(Hash_Key),Unescape_Url(value)
End If
Next

Set GetCgiVars=CgiVars
End Function


Function Unescape_Url (url)
Set RegExp1 = New RegExp
RegExp1.IgnoreCase = True
RegExp1.Global = True
RegExp1.Pattern = "%([0-9A-F]{2})"


Set Matches = RegExp1.Execute(url)
For Each Match in Matches
url = Replace(url,"%" & Match,Hex2Char(Match))
Next
Unescape_Url=url
End Function

Function Hex2Char (hexx)
Hex2Char = Chr(1*CLng("&H" & hexx))
End Function

Download this code: vbscript_cgi.vbs

#!c:\WINDOWS\system32\cscript.exe /nologo "C:\wamp\cgi-bin\vbscript_cgi.vbs"

''''''''''''''''''''''''''''''
'' testscript.vbs ''
'' Kevin DEHLINGER ''
'' 2007 / dev.pulsed.net ''
'' query some data with ''
'' wmi/wsh (some of thecode ''
'' comes from scriptomatic) ''
''''''''''''''''''''''''''''''


print "Content-type: text/html" & vbcrlf


print "<!DOCTYPE html PUBLIC ""-//W3C//DTD HTML 4.01//EN"" \""http://www.w3.org/TR/html4/strict.dtd"">" & vbcrlf & _
"<html>" & _
"<head>" & _
" <meta content=""text/html; charset=ISO-8859-1""" & _
" http-equiv=""content-type"">" & _
" <title></title>" & _
"</head>" & _
"<body>"


Set mycgivars=GetCgiVars

if mycgivars.exists("computer") then
computer=mycgivars.item("computer")
else
computer = "."
end if

print "<form method=""post"" action=""testscript.vbs"" name=""test"">Computer: <input" & _
" name=""computer"" value=""" & computer & """><input" & _
" type=""submit""></label></form>"


On Error Resume Next
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

println "Computer: " & computer & "<br \><br \>"


Set objWMIService = GetObject("winmgmts:\\" & computer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)

For Each objItem In colItems
println "Drive: " & objItem.Caption & "<br \>"
println "Description: " & objItem.Description & "<br \>"
println "VolumeName: " & objItem.VolumeName & "<br \>"
println "<br \>"
Next



print "</body></html>"

Function WMIDateStringToDate(dtmDate)
print dtm:
WMIDateStringToDate = CDate(Mid(dtmDate, 5, 2) & "/" & _
Mid(dtmDate, 7, 2) & "/" & Left(dtmDate, 4) _
& " " & Mid (dtmDate, 9, 2) & ":" & Mid(dtmDate, 11, 2) & ":" & Mid(dtmDate,13, 2))
End Function

Download this code: testscript.vbs

Archived in Windows, awesome, cgi, vbscript, web, win32 | Trackback | del.icio.us | Top Of Page

3 Responses to “Vbscript CGI (No… not ASP)”

  1. av Says:

    Awesome! Works perfectly and replaces perl :-)

  2. hMailServer-Konfiguration via CGI | WeizenSpr.eu Says:

    [...] eines CGI-Scriptes. Also habe ich mich auf die Suche gemacht, wie ich ein VBScript über CGI ansprechen und ausführen kein. Dummerweise funktionierte das Codebeispiel bei mir überhaupt nicht! Eine andere Lösung [...]

  3. boinking Says:

    u r tha man!!!!!