NetBox 2.7 使用手册

创建一个命令行解释程序

Netbox 提供了实现命令行解释器所需的全部支持,使用 Console,可以得到对控制台的控制,使用 Arguments,可以对用户的输入进行解释,使用 Script,可以根据用户的输入执行相应的脚本程序。

下面,我们用这些对象一步一步的创建一个完整的命令行解释器。我首先假设你已经了解了如何书写 NetBox 代码并运行,与此相关的信息请参阅“什么是 NetBox?”。

第一步:控制台

书写下面的代码,我们来建立一个用户输入的响应程序,所做的响应还比较简单,仅仅回显而已:

Set Console = Shell.Console

Do While true
    strCommand = Console.ReadLine
    Console.WriteLine strCommand
Loop

这段代码比较笨拙,运行起来只是呆板的接受输入并显示出来,没有任何提示,也无法退出,只能关闭窗口或按 Ctrl+C 退出程序,下面我们修改一下代码,增加退出的指令 exit,并增加一个提示符号:

Set Console = Shell.Console

Do While True
    Console.Write "#"
    strCommand = Console.ReadLine
    If LCase(strCommand) = "exit" Then Exit Do
    Console.WriteLine strCommand
Loop

再运行这段代码,会发现显示和退出都变得友好起来。然而只有友好是没有用的,下面我们开始处理用户的输入信息。

第二步:命令行

使用 Arguments 对象,我们可以将刚才读入的命令行字符串进行进一步的处理,同时显示第一个参数。

Set Console = Shell.Console
Set SubArgs = CreateObject("NetBox.Arguments")

Do While True
    Console.Write "#"
    strCommand = Console.ReadLine
    If LCase(strCommand) = "exit" Then Exit Do
    SubArgs.CommandLine = strCommand
    Console.WriteLine SubArgs(0)
Loop

现在,我们已经能够将用户输入的命令中的执行程序部分分离出来,如果还想查看用户输入的全部参数清单,可以修改为下面的代码:

Set Console = Shell.Console
Set SubArgs = CreateObject("NetBox.Arguments")

Do While True
    Console.Write "#"
    strCommand = Console.ReadLine
    If LCase(strCommand) = "exit" Then Exit Do
    SubArgs.CommandLine = strCommand
    For i = 0 To SubArgs.Count - 1
        Console.WriteLine SubArgs(i)
    Next
Loop

接下来,我们需要对用户输入的执行程序名称进行格式统一,如果用户输入的执行程序未包含了完整路径名(扩展名为 .box),则自动在名称后面添加 .box 扩展名。

Set Console = Shell.Console
Set SubArgs = CreateObject("NetBox.Arguments")

Do While True
    Console.Write "#"
    strCommand = Console.ReadLine
    If LCase(strCommand) = "exit" Then Exit Do
    SubArgs.CommandLine = strCommand

    If SubArgs.Count > 0 Then
        strExecFile = SubArgs(0)
        If LCase(Right(strExecFile, 4)) <> ".box" Then
            strExecFile = strExecFile + ".box"
        End If

        Console.WriteLine strExecFile
    End If
Loop

第三步:执行程序

在取得用户输入命令行中的执行代码部分以后,便可以对其进行装载和运行,这些操作都使用 NetBox.Script 对象,继续修改代码,增加脚本部分的操作:

Set Console = Shell.Console
Set SubArgs = CreateObject("NetBox.Arguments")

Do While True
    Console.Write "#"
    strCommand = Console.ReadLine
    If LCase(strCommand) = "exit" Then Exit Do
    SubArgs.CommandLine = strCommand

    If SubArgs.Count > 0 Then
        strExecFile = SubArgs(0)
        If LCase(Right(strExecFile, 4)) <> ".box" Then
            strExecFile = strExecFile + ".box"
        End If

        Set Script = CreateObject("NetBox.Script")

        e = Script.Load(strExecFile)
        If e = 0 Then
            Script.SetGlobalObjects

            e = Script.Run
        End If

        Set Script = Nothing
    End If
Loop

接下来创建一个新的 Script 对象,装载刚才已经格式化了的执行程序名所指定的文件,如果成功,则使用 SetGlobalObjects 将当前的内建对象传递给新的脚本程序,然后开始执行。此时,你可以在 NetBox 执行目录建立一个新的程序文件,比如名字叫做 test.box,输入下面的代码:

Shell.Console.WriteLine "Hello! Box."

Sub OnScriptError
    Shell.Console.WriteLine "OnScriptError"
End Sub

Sub OnScriptEnd
    Shell.Console.WriteLine "OnScriptEnd"
End Sub

执行 NetBox.exe 并输入 test,哈,我们的命令行解释器已经开始工作了。

第四步:错误捕捉

上面的程序,执行的时候会发现一些问题,比如如果用户输入了一个不存在的文件,程序将不显示任何内容,而且如果程序编译出错或者运行出错,也不会有任何提示。这就需要我们再进一步改进程序。首先解决文件不存在的问题。

通过查阅手册,我们知道 Load 方法在装载失败时会返回两种结果,一个是 404,另一个是 500。404 表示的是文件未找到,而 500 则表示装载时错误,可以具体查询。所以我们可以很方便时识别是否是文件未找到。继续修改代码如下:

Set Console = Shell.Console
Set SubArgs = CreateObject("NetBox.Arguments")

Do While True
    Console.Write "#"
    strCommand = Console.ReadLine
    If LCase(strCommand) = "exit" Then Exit Do
    SubArgs.CommandLine = strCommand

    If SubArgs.Count > 0 Then
        strExecFile = SubArgs(0)
        If LCase(Right(strExecFile, 4)) <> ".box" Then
            strExecFile = strExecFile + ".box"
        End If

        Set Script = CreateObject("NetBox.Script")

        e = Script.Load(strExecFile)
        If e = 0 Then
            Script.SetGlobalObjects

            e = Script.Run
        End If

        If e = 404 Then
            Console.WriteLine "Bad Command"
        End If

        Set Script = Nothing
    End If
Loop

此时,如果用户输入了一个不存在的程序名,则我们的解释器会友好的现实 “Bad Command”,然而程序中的错误还是不能捕捉,继续查阅手册,我们知道 Script 对象有一个 GetLastError 方法,可以取得详细的错误信息,于是我们的代码修改成为下面的样子:

Set Console = Shell.Console
Set SubArgs = CreateObject("NetBox.Arguments")

Do While True
    Console.Write "#"
    strCommand = Console.ReadLine
    If LCase(strCommand) = "exit" Then Exit Do
    SubArgs.CommandLine = strCommand

    If SubArgs.Count > 0 Then
        strExecFile = SubArgs(0)
        If LCase(Right(strExecFile, 4)) <> ".box" Then
            strExecFile = strExecFile + ".box"
        End If

        Set Script = CreateObject("NetBox.Script")

        e = Script.Load(strExecFile)
        If e = 0 Then
            Script.SetGlobalObjects

            e = Script.Run
        End If

        If e = 404 Then
            Console.WriteLine "Bad Command"
        ElseIf e <> 0 Then
            Set error = Script.GetLastError
            Console.WriteLine error.Category
            Console.WriteLine "Error Number: " & Hex(error.Number)
            Console.WriteLine "File: " & error.File
            Console.WriteLine "Line: " & error.Line
            Console.WriteLine error.Description & vbCRLF
            Set error = Nothing
        End If

        Set Script = Nothing
    End If
Loop

上面的代码中,在确定不是文件未找到以后,再查看是否出错,如果出错,则使用 GetLastError 方法取得脚本的详细错误信息,然后依次输出。

第五步:内建对象

在第四步中,我们调用了 SetGlobalObjects 方法传递自己的内建对象给新的脚本运行环境。这样以来我们实际上是将两个对象 NetBoxShell 传递给了新的脚本环境,这样是不够的,比如用户输入了“print Hello”,这样的命令,实际上是希望执行 print.box,并且将参数传递给它的。所以在下面的代码里面,我们使用 AddNameItem 方法添加内建对象 Arguments。

Set Console = Shell.Console
Set SubArgs = CreateObject("NetBox.Arguments")

Do While True
    Console.Write "#"
    strCommand = Console.ReadLine
    If LCase(strCommand) = "exit" Then Exit Do
    SubArgs.CommandLine = strCommand

    If SubArgs.Count > 0 Then
        strExecFile = SubArgs(0)
        If LCase(Right(strExecFile, 4)) <> ".box" Then
            strExecFile = strExecFile + ".box"
        End If

        Set Script = CreateObject("NetBox.Script")

        e = Script.Load(strExecFile)
        If e = 0 Then
            Script.SetGlobalObjects
            Script.AddNameItem "Arguments", SubArgs

            e = Script.Run
        End If

        If e = 404 Then
            Console.WriteLine "Bad Command"
        ElseIf e <> 0 Then
            Set error = Script.GetLastError
            Console.WriteLine error.Category
            Console.WriteLine "Error Number: " & Hex(error.Number)
            Console.WriteLine "File: " & error.File
            Console.WriteLine "Line: " & error.Line
            Console.WriteLine error.Description & vbCRLF
            Set error = Nothing
        End If

        Set Script = Nothing
    End If
Loop

这样,我们的新的脚本环境就有三个内建对象,NetBox,Shell,Arguments。其中 NetBox 就是我们的基本对象,Shell 是 Shell 的引用,Arguments 则是根据用户输入建立的参数对象。

总结

在这里,我们通过一个完整实用的命令行解释器的实现过程,展示了 ConsoleArgumentsScript 三个对象的具体使用,涉及到的属性与方法,可以参考对象手册中的讲解进行对照。同时,命令行解释器的实现,也扩充了 NetBox 的执行方式,可以随意执行给定的 .box 程序,方便了对其他对象的学习与调试。


版权所有: 2003- 网络盒子