vbscriptscriptcontrolmsscriptcontrol

How can we programmatically know the syntax error using msscript.ocx?


I have implemented msscript.ocx using c# and it works for VBScript.

Consider the following VBScript code:

For i = 0 To 5

  'The following line has missing 'Then'. It should show an error.
  If i = 2
    Exit For
  End If

Next

How can we tell if there is an error in line containing If (missing Then) without running the script?


Solution

  • You get the error when loading.

    Set Arg = WScript.Arguments
    set WshShell = createObject("Wscript.Shell")
    Set Inp = WScript.Stdin
    Set Outp = Wscript.Stdout
    
    Sub VBSCmd
        RawScript = Arg(1)
        'Remove ^ from quoting command line and replace : with vbcrlf so get line number if error
        Script = Replace(RawScript, "^", "")
        Script = Replace(Script, "'", chr(34))
        Script = Replace(Script, ":", vbcrlf)
        'Building the script with predefined statements and the user's code
        Script = "Dim gU" & vbcrlf & "Dim gdU" & vbcrlf & "Set gdU = CreateObject(" & chr(34) & "Scripting.Dictionary" & chr(34) & ")" & vbcrlf & "Function UF(L, LC)" & vbcrlf & "Set greU = New RegExp" & vbcrlf & "On Error Resume Next" & vbcrlf & Script & vbcrlf & "End Function" & vbcrlf
    
        'Testing the script for syntax errors
        On Error Resume Next
        set ScriptControl1 = wscript.createObject("MSScriptControl.ScriptControl",SC)
            With ScriptControl1
                .Language = "VBScript"
                .UseSafeSubset = False
                .AllowUI = True
            .AddCode Script
        End With
        With ScriptControl1.Error
            If .number <> 0 then
                Outp.WriteBlankLines(1)
                Outp.WriteLine "User function syntax error"
                Outp.WriteLine "=========================="
                Outp.WriteBlankLines(1)
                Outp.Write NumberScript(Script)
                Outp.WriteBlankLines(2)
                Outp.WriteLine "Error " & .number & " " & .description
                Outp.WriteLine "Line " & .line & " " & "Col " & .column
                Exit Sub
            End If
        End With
    
        ExecuteGlobal(Script)
    
        'Remove the first line as the parameters are the first line
        'Line=Inp.readline  
        Do Until Inp.AtEndOfStream
            Line=Inp.readline
            LineCount = Inp.Line 
    
            temp = UF(Line, LineCount)
            If err.number <> 0 then 
                outp.writeline ""
                outp.writeline ""
                outp.writeline "User function runtime error"
                outp.writeline "==========================="
                Outp.WriteBlankLines(1)
                Outp.Write NumberScript(Script)
                Outp.WriteBlankLines(2)
                Outp.WriteLine "Error " & err.number & " " & err.description
                Outp.WriteLine "Source " & err.source
    
                Outp.WriteLine "Line number and column not available for runtime errors"
                wscript.quit
            End If
            outp.writeline temp
        Loop
    End Sub
    

    Vbs

    filter vbs "text of a vbs script"
    

    Use colons to seperate statements and lines. Use single quotes in place of double quotes, if you need a single quote use chr(39). Escape brackets and ampersand with the ^ character. If you need a caret use chr(136).

    The function is called UF (for UserFunction). It has two parameters, L which contains the current line and LC which contains the linecount. Set the results of the script to UF. See example.

    There are three global objects available. An undeclared global variable gU to maintain state. Use it as an array if you need more than one variable. A Dictionary object gdU for saving and accessing previous lines. And a RegExp object greU ready for use.

    Example This vbs script inserts the line number and sets the line to the function UF which Filter prints.

    filter vbs "uf=LC ^& ' ' ^& L"<"%systemroot%\win.ini"
    

    This is how it looks in memory

    Dim gU
    Set gdU = CreateObject("Scripting.Dictionary")
    Set greU = New RegExp
    
    Function UF(L, LC)
    
    ---from command line---
    uf=LC & " " & L
    ---end from command line---
    
    End Function
    

    If there is a syntax error Filter will display debugging details.