<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki2.lessokaji.com/index.php?action=history&amp;feed=atom&amp;title=Startup.iocmd%E8%84%9A%E6%9C%AC%E8%AF%AD%E6%B3%95</id>
	<title>Startup.iocmd脚本语法 - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki2.lessokaji.com/index.php?action=history&amp;feed=atom&amp;title=Startup.iocmd%E8%84%9A%E6%9C%AC%E8%AF%AD%E6%B3%95"/>
	<link rel="alternate" type="text/html" href="https://wiki2.lessokaji.com/index.php?title=Startup.iocmd%E8%84%9A%E6%9C%AC%E8%AF%AD%E6%B3%95&amp;action=history"/>
	<updated>2026-05-16T16:07:35Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki2.lessokaji.com/index.php?title=Startup.iocmd%E8%84%9A%E6%9C%AC%E8%AF%AD%E6%B3%95&amp;diff=1044&amp;oldid=prev</id>
		<title>Artheru：​Initial bilingual draft (auto-published)</title>
		<link rel="alternate" type="text/html" href="https://wiki2.lessokaji.com/index.php?title=Startup.iocmd%E8%84%9A%E6%9C%AC%E8%AF%AD%E6%B3%95&amp;diff=1044&amp;oldid=prev"/>
		<updated>2026-05-16T14:00:25Z</updated>

		<summary type="html">&lt;p&gt;Initial bilingual draft (auto-published)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 概述 / Overview ==&lt;br /&gt;
`startup.iocmd` 是 Medulla 启动时执行的 ''迷你脚本''。语法极简：每行一条命令，支持对象加载、字段读写、方法调用。它的目的是让现场调试人员能在不写 C# 的情况下加载和初始化插件。&lt;br /&gt;
&lt;br /&gt;
`startup.iocmd` is the tiny script Medulla executes at boot. The grammar is minimal — one command per line, with object loading, field read/write, and method invocation. Its purpose is to let on-site engineers load and initialise plugins without writing C#.&lt;br /&gt;
&lt;br /&gt;
实现：`D:\src\M2\MedullaCore\Core\MedullaScriptEngine.cs:22-130`。&lt;br /&gt;
Implementation: `D:\src\M2\MedullaCore\Core\MedullaScriptEngine.cs:22-130`.&lt;br /&gt;
&lt;br /&gt;
启动入口：`Startup.runScript(filename)` 在 CWD 找 `startup.iocmd`，逐行执行。&lt;br /&gt;
Boot entry: `Startup.runScript(filename)` reads `startup.iocmd` from CWD line by line (`Startup.cs:374-402`).&lt;br /&gt;
&lt;br /&gt;
== 命令语法 / Command grammar ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 形式 / Form !! 语法 / Syntax !! 示例 / Example !! 语义 / Semantics&lt;br /&gt;
|-&lt;br /&gt;
| 加载 + 赋值 / Load + assign || `name = io load &amp;lt;dll&amp;gt;` || `lidar = io load plugins/Lidar.dll` || 加载 DLL，反射找 `MainIOObject`，实例化，注册到 `Objects[name]`&lt;br /&gt;
|-&lt;br /&gt;
| 工厂方法 / Factory method || `name = obj method arg1 arg2 ...` || `lidar = io init WLR716Lidar 192.168.0.2 2110` || 调用 obj.method 并把返回赋值给 name&lt;br /&gt;
|-&lt;br /&gt;
| 方法调用 / Method call || `name method arg1 arg2 ...` || `cart Init` || 调用 name.method（无返回）&lt;br /&gt;
|-&lt;br /&gt;
| 字段读 / Field read || `name.field` || `cart.batteryPercent` || 反射读字段或 property，控制台输出&lt;br /&gt;
|-&lt;br /&gt;
| 字段写 / Field write || `name.field = value` || `cart.TimeoutThreshold = 1000` || 反射写；`TypeDescriptor.ConvertFromString` 解析 value&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
解析规则：按空格分词；引号内当一个 token。&lt;br /&gt;
Parsing: split on whitespace; quoted strings count as one token.&lt;br /&gt;
&lt;br /&gt;
== 支持的参数类型 / Supported parameter types ==&lt;br /&gt;
* 整型 / Integers: `short`, `ushort`, `int`, `uint`, `long`, `ulong`&lt;br /&gt;
* 浮点 / Floats: `float`, `double`&lt;br /&gt;
* `bool`：`true` / `false`&lt;br /&gt;
* `string`：可加引号 `&amp;quot;with spaces&amp;quot;` 或不加&lt;br /&gt;
* `byte[]`：十六进制串 `0x12AB`&lt;br /&gt;
* `IOObject` 引用：按 `Objects[name]` 解析（即用其它对象的名字）&lt;br /&gt;
&lt;br /&gt;
Hex literal: `0x12AB` for integer types.&lt;br /&gt;
&lt;br /&gt;
Overload resolution: by name + arity, or variadic `object[]` (`MedullaScriptEngine.cs:138-144`).&lt;br /&gt;
&lt;br /&gt;
== 完整示例 / Full example ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
# Lidar plugin&lt;br /&gt;
lidar = io load plugins/LidarController.dll&lt;br /&gt;
lidar = lidar init WLR716Lidar 192.168.0.2 2110&lt;br /&gt;
lidar Start&lt;br /&gt;
lidar.TimeoutThreshold = 1000&lt;br /&gt;
&lt;br /&gt;
# Cart adapter plugin&lt;br /&gt;
cart = io load plugins/MyCart.dll&lt;br /&gt;
cart Init&lt;br /&gt;
cart.brakeOn = false&lt;br /&gt;
&lt;br /&gt;
# Camera&lt;br /&gt;
cam = io load plugins/Camera.dll&lt;br /&gt;
cam = cam init 192.168.0.50 8081&lt;br /&gt;
cam Start&lt;br /&gt;
&lt;br /&gt;
# Diagnostics: open the LidarController's web utility for the loaded lidar&lt;br /&gt;
# (it'll appear at https://&amp;lt;host&amp;gt;:8081/lidar/ShowFrame)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web endpoint 自动注册 / Auto web-endpoint registration ==&lt;br /&gt;
赋值语句 `name = io load ...` 不仅注册对象，还会把对象上 `[IOObjectWebUtility]` 标注的方法自动挂到 HTTP 路径 `/&amp;lt;name&amp;gt;/&amp;lt;methodname&amp;gt;`。&lt;br /&gt;
The assignment `name = io load ...` also auto-registers any `[IOObjectWebUtility]` methods at `/&amp;lt;name&amp;gt;/&amp;lt;methodname&amp;gt;`.&lt;br /&gt;
&lt;br /&gt;
启动后可访问 `https://&amp;lt;host&amp;gt;:&amp;lt;MedullaIO.CPort&amp;gt;/&amp;lt;name&amp;gt;/&amp;lt;method&amp;gt;` 调用插件方法。&lt;br /&gt;
After boot, hit `https://&amp;lt;host&amp;gt;:&amp;lt;MedullaIO.CPort&amp;gt;/&amp;lt;name&amp;gt;/&amp;lt;method&amp;gt;` to invoke.&lt;br /&gt;
&lt;br /&gt;
== 注释与空行 / Comments &amp;amp; blank lines ==&lt;br /&gt;
* 空行 / blank lines: 忽略&lt;br /&gt;
* `# 开头` / lines starting with `#`：注释&lt;br /&gt;
* 没有 ''多行命令''；每条命令必须写在一行。&lt;br /&gt;
&lt;br /&gt;
== 错误处理 / Error handling ==&lt;br /&gt;
脚本里某行失败 → ''继续''执行下一行；错误打到 DLog + Hedingben toast。所以 `startup.iocmd` 是 &amp;quot;尽力而为&amp;quot;模型 —— 你应该用 web 端点或控制台后续确认状态，不要假设全部成功。&lt;br /&gt;
&lt;br /&gt;
Failed lines log to DLog + Hedingben toast and execution continues. `startup.iocmd` is &amp;quot;best-effort&amp;quot; — confirm state via web endpoint or console afterwards.&lt;br /&gt;
&lt;br /&gt;
== 扩展点 / Extension hooks ==&lt;br /&gt;
* 添加新的内建函数：扩展 `MedullaScriptEngine.evaluate` (line 80+)。&lt;br /&gt;
* 加新的参数类型：扩展 `MedullaScriptEngine.cs:69` 的 type coercion switch。&lt;br /&gt;
* 保持语法最简 —— 没有括号、没有嵌套调用。'''单行可读''' 是它的设计原则。&lt;br /&gt;
&lt;br /&gt;
* New built-in functions: extend `MedullaScriptEngine.evaluate` (line 80+).&lt;br /&gt;
* New parameter types: extend the coercion switch at line 69.&lt;br /&gt;
* Keep the grammar minimal — no parens, no nested calls. '''Single-line readability''' is the design.&lt;br /&gt;
&lt;br /&gt;
== 注意 / Caveats ==&lt;br /&gt;
* `startup.iocmd` 在 ''CWD'' 加载，不在 Medulla 安装目录 —— 启动脚本要把工作目录设到正确位置。&amp;lt;br&amp;gt;&lt;br /&gt;
  Loaded from CWD, not Medulla's install dir — your launcher must set the working directory.&lt;br /&gt;
* 没有 `if / for / while` —— 控制流需要写 C# 插件。&lt;br /&gt;
* `name` 标识符不能含 `.` 或 `=` 或空格。&lt;br /&gt;
&lt;br /&gt;
== 相关页面 / See also ==&lt;br /&gt;
* [[Special:MyLanguage/插件契约与打包约定|插件契约与打包约定]]&lt;br /&gt;
* [[Special:MyLanguage/IOObject属性参考|IOObject属性参考]]&lt;br /&gt;
* [[Special:MyLanguage/Medulla软件架构|Medulla软件架构]]&lt;br /&gt;
* [[Special:MyLanguage/Medulla|Medulla]] / [[Special:MyLanguage/Medulla-API|Medulla-API]]&lt;br /&gt;
&lt;br /&gt;
[[Category:二次开发相关说明]]&lt;br /&gt;
[[Category:开发手册]]&lt;/div&gt;</summary>
		<author><name>Artheru</name></author>
	</entry>
</feed>