概要
- ExcecuteGlobalを使って、外部のVBScriptにオブジェクトを渡す
- VisualStudioを使ってVBScriptのデバッグ(ステップ実行,変数の参照など)する
「VisualStudioを使ってVBScriptのデバッグ」は、
Blogs By Kresten: VBScript Projects in Visual Studio、メモ: Visual Studio を使って VBScript の開発を行う - 高東ソフトウェアサービス、VBScript でもデバッグしながら開発を行える | ええかげんブログ(本店)と同じ内容なので割愛します。
ポイントは、「CtrlC+F5(デバッグなしで開始)」で実行することです。
※F5だと別プロセスのVisualStudioでデバッグ開始されてしまうようです。
動機
サクラエディタのマクロとプラグインは、マクロ/プラグインのスクリプト内で生成しない(=スクリプト実行時にエディタから渡される)インターフェースオブジェクト(Editorオブジェクトなど)を使って、エディタの情報取得・操作を行います。※詳しくは、プラグイン開発者ガイド(plugin.chm)を参照
たいていはマクロ/プラグインのスクリプト内に、インターフェースオブジェクトを期待する(=エディタを操作する)ロジックがあるので、↓のようにエディタ経由でvbs実行をすると問題ありませんが、
スクリプトをダブルクリックで実行すると、↓のようなエラーが発生するものになります。
ダブルクリックでちょっとしたテストを実施できないのは、もどかしいこともあったので、「vbsをダブルクリックしてテストを実行する方法はないか」と考えていました。
そんなときに、
- VBScriptで悩んだことメモ - Qiita→「VBSでInclude」
- VBScript 基礎文法最速マスター - CX's VBScript Diary→「9. 知っておいたほうがよい文法」
- VBScript でもデバッグしながら開発を行える | ええかげんブログ(本店)
を見かけたので使ってみよう・・・というのが今回の動機です。
詳細
ExcecuteGlobalを使って、外部のVBScriptにオブジェクトを渡す
ソース
(1) test_external_script.vbs内に適当なクラス(SharedObjClass)を作る。
(2) SharedObjClassのインスタンス(Editor)を作る
(3) Editorのメンバ変数(GetFilename)にGetRefで適当な関数Func1を割り当てる
(4) 外部のスクリプト(external_script.vbs)を読み込む
(5) ExcecuteGlobalを使って 読み込んだexternal_script.vbs を実行する
(6) external_script.vbs側でEditor.GetFilename を呼び出す
(7) external_script.vbs側でEditor.FuncSetByExternalに適当な関数Func2を割り当てる
(8) test_external_script.vbs側でFuncSetByExternalを呼び出す
VisualStudio側は、VBScript でもデバッグしながら開発を行える | ええかげんブログ(本店)とほぼ同じですが、
コマンドとコマンド引数は、
コマンド:wscript.exe
コマンド引数:test_external_script.vbs //X
としています。
Option Explicit
' (1) test_external_script.vbs内に適当なクラス(SharedObjClass)を作る。
Class SharedObjClass
Public GetFilename
Public FuncSetByExternal
End Class
' (2) SharedObjClassのインスタンス(Editor)を作る
Dim Editor
Set Editor = New SharedObjClass
' (3) Editorのメンバ変数(GetFilename)にGetRefで適当な関数Func1を割り当てる
Function Func1()
Func1 = Wscript.ScriptFullName
End Function
Set Editor.GetFilename = GetRef("Func1")
'(4) 外部のスクリプト(external_script.vbs)を読み込む
Dim externalScript
Set externalScript = CreateObject("Scripting.FileSystemObject").OpenTextFile("external_script.vbs")
' (5) ExcecuteGlobalを使って 読み込んだexternal_script.vbs を実行する
ExecuteGlobal externalScript.ReadAll
externalScript.close
' (8) test_external_script.vbs側でFuncSetByExternalを呼び出す
MsgBox(Editor.FuncSetByExternal())
Option Explicit
' (6) external_script.vbs側でEditor.GetFilename を呼び出す
MsgBox(Editor.GetFilename())
' (7) external_script.vbs側でEditor.FuncSetByExternalに適当な関数Func2を割り当てる
Function Func2()
Func2 = "external_script.vbs"
End Function
Set Editor.FuncSetByExternal = GetRef("Func2")
実行結果
「(5) ExcecuteGlobalを使って 読み込んだexternal_script.vbs を実行する」の直前で止めます。
F10(ステップオーバー) or F11(ステップイン) で進めていくと、Script Documents内にeval codeが現れ、↓のMsgBoxが出ます。表示されているファイルパスは、test_external_script.vbsのパス(Func1 = Wscript.ScriptFullNameで取得したもの)です。
これで、external_script.vbs側にEditorが渡り、メソッドを呼び出せたことがわかりました。
eval code内は"external_script.vbs"と同一です。ちなみに、eval code内にブレークポイントを設定することができず、"external_script.vbs"にブレークポイントを設定しても素通りします。
(8)を実行すると、(7) のFunc2が呼び出せていることがわかります。
これで、external_script.vbs側でかけたEditorに対する変更がtest_external_script.vbs側にも反映されていることがわかります。
最後に、test_external_script.vbsをダブルクリックして実行すると、external_script.vbsをエラーなしで実行することができることが確認できます。
まとめ
この仕組みを使うと、サクラエディタのマクロ/プラグインのスクリプト内に、模擬インターフェースオブジェクト(Editor)を渡すことができるので、ダブルクリックで実行できるラッパー的なテスト用スクリプトを作ることができます。
参考
- VBScriptで悩んだことメモ - Qiita→「VBSでInclude」
- VBScript 基礎文法最速マスター - CX's VBScript Diary→「9. 知っておいたほうがよい文法」
クラス関連
GetRef関数関連
- VBS - FSWikiLite→「関数のリファレンスを使う!!」
VisualStudio関連