工作流与 C#
内置基础节点、C# 关键词与运算符对应、文本拼接及集合处理教程见基础节点。SDK 1.6 的纯数据操作也可用 context.InvokeAsync("core.text.concat", ...) 调用;图形生成的 C# 保留控制节点与子图,使用同一个引擎执行。
工作流文件使用 schemaVersion 1,kind 为 Graph 或 CSharp。JSON 包含输入输出端口、inputDefaults、variables、graph/code、pluginVersions、节点的 trigger 配置与布局。旧版 triggers 列表读取后迁移为节点。导出 .xfeworkflow 是包含 workflow.json 的 ZIP;导入创建新的工作流 ID。
参数与数据连线
固定值在节点属性中填写;动态值从上游输出端口拖线连接到对应输入,工作流输入可在设置中声明并从“开始”的同名输出连接。连线值覆盖同名固定参数,未提供参数使用端口默认值。端口按类型检查,需要时插入“类型转换”节点。
消息内容直接由数据连线传递,不在消息里插入变量表达式或包装字段。连线上的对象、数组、文本及其他值保留原始内容,不对其中看起来像绑定表达式的字段再次求值。凭据在“设置 → 凭据”创建,在专用凭据属性中选择引用即可。
触发器从节点库拖入画布,在节点属性中配置。图形工作流从触发节点沿连线执行,纯 C# 工作流触发后执行代码主体;完整事件在 inputs.trigger.data,可以通过输入映射把事件字段交给任意节点或插件。配置、字段与工作流联动示例。
数组遍历与子图
使用“逻辑控制 → 遍历集合”,将 JSON 数组填写或连接到 items。选中节点后点击“编辑子图:body”,把每项要执行的步骤放入子图。在子图放置“当前循环项”,item 输出当前元素,index 输出从 0 开始的数字序号。把 item 连到“日志操作 → 输出日志”的 message,即可逐项原样输出,消息参数保持空白。
主图的 next 在全部迭代结束后执行;results 收集每轮子图的输出对象,空数组得到 []。循环结束后恢复之前的元素变量与序号,其他变量修改保留。普通执行连线不能连回前面的节点,循环通过结构化子图实现。
导入“数组遍历 · 逐项输出日志”模板,无需插件或外部服务。完整教程包含对象数组、动态输入、嵌套遍历、结果结构及日志导出。
运行与节点调试
运行输出只显示用户/插件主动日志和必要错误,开始、结束及成功事件不写入日志。编辑器 F5 运行/继续,F9 设置选中节点断点,F10 越过、F11 进入结构化子图,Shift+F5 停止;暂停数据在底部“调试”页查看。断点、作用域、超时与 C# 调试范围。
企业微信联系人遍历模板将 contacts 数组连到 items,在循环体通过“当前联系人”的 item 连线传递完整的原始联系人对象。连接客户端与缓存范围。
C# 工作流
从图形化切到 C# 时,会生成当前图的 C# 表示,包含真实节点、参数、数据与执行连线、代码节点和结构化子图。生成的 CreateGraph 可直接编辑,最后由 context.ExecuteGraphAsync 交给统一引擎执行,保持与图形相同的分支、变量和错误定位。
未手动编辑的生成代码会在图形变化后更新;已手动编辑的代码会保留。编辑器右上角“从图形重新生成 C#”可预览后替换,替换前的代码会持久化备份,“还原生成前的代码”可恢复。切回图形会保留原图;任意手写 C# 不会自动反向转换成节点。
using System.Threading;
using System.Threading.Tasks;
using System.Text.Json.Nodes;
using XFEWorkflow.Abstractions;
public sealed class DailyReport : IWorkflow
{
public async ValueTask<JsonObject> ExecuteAsync(
IWorkflowContext context, CancellationToken cancellationToken)
{
var data = await context.InvokeAsync("xfe.http.request", new()
{
["url"] = context.Inputs["source"]?.DeepClone(), ["method"] = "GET"
}, cancellationToken);
var ai = await context.InvokeAsync("xfe.ai.chat", new()
{
["endpoint"] = "https://api.openai.com/v1",
["model"] = context.Inputs["model"]?.DeepClone(),
["credential"] = "ai.key", ["prompt"] = data["text"]?.DeepClone()
}, cancellationToken);
await context.InvokeAsync("xfe.wecom.send", new()
{
["credential"] = "wecom.webhook", ["format"] = "markdown",
["content"] = ai["text"]?.DeepClone()
}, cancellationToken);
return ai;
}
}
在工作流设置中添加 source、model 的 inputDefaults,然后配置凭据。模型应选用目标服务支持的名称。AI 使用 Chat Completions 兼容协议,完整 messages 数组也可通过参数传入。
C# 节点仅填写方法体,可使用 context、cancellationToken、JsonObject 以及 System/Linq/Threading 常用命名空间。节点返回 JsonObject,输出位于该节点的 result 端口:
var text = context.Inputs["text"]?.ToString() ?? "";
await context.LogAsync(text, cancellationToken);
return new JsonObject { ["upper"] = text.ToUpperInvariant() };
子流程调用:await context.InvokeWorkflowAsync("工作流ID", new JsonObject(), cancellationToken)。图形流程使用“子工作流”节点,可与代码流程互调。动态调用所需插件版本应列在父流程 pluginVersions 中。
浏览器
用 xfe.browser.open 获得 tab 资源句柄,再连接 navigate/wait/input/click/extract/script/screenshot/download。参数 frame 留空表示主页面,0 表示第一个 iframe。输入节点会触发 input/change 事件。脚本节点示例:return document.title;。
同一登录配置的手动浏览器标签可先完成登录,再由流程使用该配置。下载参数是目标文件的绝对路径。点击、输入、读取等操作依赖当前网页的 DOM 与选择器,网页改版后需更新定位。
桌面
定位优先使用 processId,配合 automationId 或 name;也可提供精确窗口标题 window。先使用元素拾取节点取得控件描述。UIA Value 模式支持中文填写;其他控件回退到物理输入。
输入序列为 steps 数组,例如:
{"steps":[{"operation":"text","text":"中文"},{"operation":"keys","keys":"LeftControl+S"},{"operation":"delay","milliseconds":200}]}
实际字段和可选项以节点清单为准。HID 不支持 Unicode 或绝对定位,涉及这些能力应选择 standard 后端。