aardio + VBScript 混合開發

2022-09-27 15:00:16

aardio 與 VBScript 可以直接混合程式設計,VBScript 屬於 Windows 系統自帶元件 —— 可以方便地生成獨立 EXE 程式。

快速入門

首先建立 VBScript 直譯器,aardio 程式碼範例:

import web.script;
var vm = web.script("VBScript")

可以將 aardio 物件(表、陣列、函數)直接賦值為 vm 直譯器的成員,然後就可以在 VBScript 中呼叫這些 aardio 物件了,aardio 程式碼範例如下:

//新增一個 aardio 函數到 VBScript
vm.external = {
    add = function(a,b){
        return a + b;
    };
}

用上面的方法模擬 WScript 物件:

vm.WScript = { 
    CreateObject = com.CreateObject;
    GetObject = com.GetObject;
    Echo = function(...){
        console.log(...);
    };
}

import console;

下面指定要執行的 VBScript 程式碼,也可以用 vm.doScript() 函數執行 VBScript 。

vm.script = /*
Function TestFunction(a,b) 
    Dim shell, ns, item
    
    '建立 COM 物件
    Set shell = CreateObject("Shell.Application") 
    Set ns = shell.NameSpace("::{7007ACC7-3202-11D1-AAD2-00805FC1270E}")
    
    '遍歷 COM 物件
    For Each item In ns.Items()
        '注意 VBScript 呼叫方法且不接收返回值時,不要加括號。
         WScript.Echo item.Name,item.Path
    Next
    
   TestFunction = external.add(a(0),b(0))
End Function
*/ 

注意在 aardio 中 /* */ 這樣的段註釋可以賦值為字串 。因為 aardio 要求段註釋首尾的星號數目一致,所以很適合用於包含其他程式語言的程式碼。請參考:aardio 程式語言快速入門——語法速覽

aardio 可以通過 vm.script.函數名() 直接呼叫 VBScript 函數,aardio 程式碼範例:

var ret = vm.script.TestFunction({12,13},{2,3});
console.log( ret );

以上範例的完整原始碼請參考 aardio 自帶範例:

▶ 執行 VBScript 並獲取表示式的值

aardio 程式碼範例:

import web.script;
var vm = web.script("VBScript")
 
var version = vm.eval(
`ScriptEngine() & " " & ScriptEngineMajorVersion() &_
"."  & ScriptEngineMinorVersion() & "."  & ScriptEngineBuildVersion()`
);

import console;    
console.log(version);
console.pause();

▶ VBScript 解析 JSON

VBScript 解析 JSON 不是很方便,我們用 aardio 為 VBScript 新增 JSON 解析功能。
aardio 的 JSON 解析器相容JSON,JSONP,JSON5,部分類 YAML 語法。下面看 aardio 程式碼範例:

//匯入 VBScript + JSON 支援庫
import web.script.json;

//建立 VBScript 解析器
var vm = web.script("VBScript");

//新增 VBScript 函數
vm.external = {
    log = function(...){
        console.log(...);
    }; 
}
import console;

//執行 VBScript
vm.script = /*
Function TestFunction() 

    '解析 JSON
    Set jObject = JSON.parse("{name:{a:123:b:456,c:[1,2,3]}}" ) 
    jObject.newKey = "測試"
    
    arr = jObject.name.c
    arr(0) = "測試"
    
    '遍歷 JSON 陣列
    For Each item In arr
         external.log item
    Next
    
     TestFunction =  arr(0) 
End Function
*/ 

//呼叫 VBScript 函數。
var ret = vm.script.TestFunction();
console.dump(ret);

console.pause();

▶ 編寫 VBScript 擴充套件庫

這裡說明一下擴充套件 VBScript 功能的 aardio 擴充套件庫 web.script.json 是如何寫出來的。

首先需要了解 web.script 不僅僅是可以用於執行 VBScript ,也可以用於執行 JavaScript ,參考:aardio + JavaScript 快速開發桌面軟體,體積小使用系統自帶ES6 元件

web.script 在建立指令碼直譯器時,會檢查 web.script.preload 名稱空間下的所有擴充套件物件,先看一下 web.script 的建構函式的相關 aardio 程式碼:

import com;
namespace web;

class script {
    ctor(language = 'JScript'){{
        this.msc = ..com.CreateObject("ScriptControl");
            
        // …… 其他程式碼省略

        this.reset = function(){
            this.msc.Reset();
            
            //指令碼語言名稱轉為小寫
            var lang = ..string.lower(this.msc.Language);
        
            //遍歷 web.script.preload 名稱空間
            for(k,v in self.preload){
                
                //如果擴充套件物件的 language 表指定了對當前語言啟用擴充套件
                if(!v.language || v.language[lang]){
                    
                    //執行擴充套件物件的 code 屬性指定的指令碼程式碼
                    if(v.code)this.msc.AddCode(v.code);
                    
                    //執行擴充套件物件的 init 函數
                    if(v.init)v.init(this.msc);
                }
            }    
        }
        this.reset();
        
        // …… 其他程式碼省略
    }}  
}

web.script.preload 名稱空間下的擴充套件物件,可選指定以下三個屬性:

1、屬性 language 可用表物件指定支援哪些語言。

2、屬性 code 可用於指定預設載入的指令碼程式碼。

3、屬性 init 可指定初始化執行的函數。

然後我們再看一下 web.script.json 擴充套件庫的 aardio 程式碼:

import web.json;
import web.script;
namespace web.script.json{};

// JavaScript 擴充套件
namespace web.script.preload.json3 {
    language = {
        javascript = true;
        jscript = true;
    }
    code =  //省略JSON3 原始碼
}

// VBScript 擴充套件
namespace web.script.preload.json3vbs {
    language = {
        vbscript = true;
        vbs = true;
    }
    init = function(msc){
        msc.AddObject("JSON",{ 
            parse = function(...){ 
                return ..web.json.parse(...);
            };
            stringify = function(...){ 
                return  ..web.json.stringify(...)
            };     
        })
    }
}