Skip to Content
Plugin 開發Batch/headless

Batch/headless

前面的 Plugin 都是在互動的主程式裡試的。這一章講不開畫面的用法:在產線腳本、CI、.bat 裡呼叫主程式, 掛上你的 Plugin,執行它的自訂指令,然後依結果決定下一步。

兩個名詞

  • Batch(批次):主程式以 --batch(或 --run、--cmd)啟動,不開畫面,指令的輸出印在標準輸出,跑完就結束。
  • headless:Plugin 掛載時沒有對應的面板。Batch 沒有畫面,所以掛上去的 Plugin 一定是 headless; 另外,如果你的 Plugin 宣告了「沒有面板」(panel_mode 是 NX_PANEL_MODE_NONE),互動模式下掛載也是 headless(帶 @p<N> 也會被忽略)。 headless 的 Plugin 收不到任何「從畫面來的事件」(按鍵、widget 操作、繪圖),但 init、probe、輪詢、自訂指令、cleanup 都正常,見生命週期與執行緒。 這正是它的用途:讓自訂指令與背景工作不佔任何面板。

怎麼跑

nexus_tui.exe 與 nexus_gui.exe 都支援批次旗標,行為一樣。旗標有:

旗標意思
--batch不開畫面,純文字輸出到標準輸出
--cmd "<指令>"執行一條指令,可以重複,最多 16 條,依出現順序執行
--run <script.lua>執行 Lua 腳本後結束,見Lua 自動化
--dongle <名稱>依名稱選後端,例如 mock。名稱不存在就列出實際掃到的清單並以非 0 結束,不會自動改用別的後端
--addr <hex>預設的 I2C 位址(7-bit,0x00~0x7F)
--log-level <mask>Log 等級遮罩

批次模式支援標準輸出重導向(> out.txt)。一個實際的例子(用第一個 Plugin 3的 hello_ic、模擬後端):

nexus_tui.exe --batch --dongle mock --cmd "p hello_ic" --cmd "hello" --cmd "read"

輸出:

PLUGIN: switched to hello_ic (probe ok) [hello_ic] hello_ic: hello! [hello_ic] hello_ic: reg 0x00 = 0x00
  • Batch 只掃描 plugins\ 裡的 DLL。
  • 批次沒有面板,所以 p hello_ic 不需要(也不用)加 @p<N>。
  • 你的 handler 用 LogWrite 寫的行,會在指令跑完後原樣印到標準輸出,前面帶 [Plugin名稱]。
  • Plugin 的 on_config_load 會被呼叫,on_config_save 永遠不會:批次只讀不寫 config.ini,見設定持久化。

Exit Code:Plugin 指令失敗會反映在這裡

批次結束時的 Exit Code 是第一條失敗指令的錯誤碼絕對值,全部成功是 0,失敗那一條之後的指令不會再執行。 對 Plugin 自訂指令,規則是:

情況結果
handler 回傳 ERR_OK繼續下一條,Exit Code 不受影響
handler 回傳其他值(例如 ERR_HW_OFFLINE,-40)往 stderr 印 cmd N ('...') failed: plugin command failed (see log above),停止後續指令,Exit Code 是 40
指令名稱不存在印 unknown command,Exit Code 是 7
p <name>/plugin switch/plugin restart 之後 probe() 回報失敗(沒帶 force)批次會等 probe 跑完再回:往 stderr 印 nexus_tui: cmd N ('p X') failed: rc=-E: PLUGIN: switched to X (probe failed rc=-E; kept in failed state),停止後續指令,Exit Code 是 E(probe() 回傳碼的絕對值);probe() 或 on_config_load 崩潰回 ERR_CALLBACK_CRASHED(Exit Code 82);10 秒內等不到結果回 ERR_TIMEOUT(Exit Code 6)。通過(或沒實作 probe)印 (probe ok),帶 force 且探測失敗印 (probe failed; kept by force),兩者都繼續

下面是沒有接 dongle、也不帶 --dongle 時,這一行指令的實際輸出(hello_ic 的 read 把 ExecSync 的錯誤碼原樣回傳):

nexus_tui.exe --batch --cmd "p hello_ic force" --cmd "read" --cmd "hello"
nexus_tui: cmd 2 ('read') failed: plugin command failed (see log above) PLUGIN: switched to hello_ic (probe ok) adapter scan: dir=...\dongles found=0 loaded=0 rejected=0 dongle connect failed (auto) (rc=-40) - hardware is offline - Try: check the dongle is plugged in, ... [hello_ic] hello_ic: read 0x00 failed, rc=-40 job #2 failed: op=205 addr=0x00 offset=0x0000 len=0 (rc=-40) - hardware is offline - ...

(p hello_ic force 讓沒有硬體時也能掛上。行尾的 ... 是我把長行截短了。)

(結束時 %ERRORLEVEL% 是 40,後面的 hello 沒有執行。)

這裡有兩個要注意的地方:

  1. 失敗要回傳錯誤碼。 如果你的 handler 只是寫一行錯誤 Log、卻 return ERR_OK,Batch 看到的是成功,Exit Code 是 0。 自己的自訂指令處理函式,遇到錯誤就把錯誤碼回傳出去,就像 hello_ic 的 read 那樣。
  2. handler 要在 10 秒內做完。 Batch 最多等 10 秒。超過的話,這一條會被誤判成 unknown command。 要在批次裡跑的指令請設計成短的;長時間的工作拆成幾條指令。

想確認指令「做了什麼」,除了 Exit Code,也去看輸出的 Log(腳本可以從標準輸出解析)。

除錯批次的小訣竅

  • 先在互動模式把指令跑通,再放進批次。
  • 沒有硬體時,一律加 --dongle mock。
  • 批次沒有掛載成功(例如 p hello_ic 找不到)時,先確認 plugins\ 裡真的有那顆 DLL、且架構與主程式相同(x86/x64),見架構要對:x86/x64。
  • 用 --cmd "plugin list" 看有沒有被掃到。