你好,我是Hamibot开发者,遇到一个严重的脚本路径问题,麻烦协助解答:

【设备与环境】

  • 手机:小米 Note 13 / 小米 Note 9 Pro
  • 系统:MIUI 14(Android 13)
  • Hamibot版本:1.6.7
  • 脚本位置:所有脚本(守护脚本 wla_daemon.js、业务脚本 douyin_follow.js)均在Hamibot同一账号、同一分组内,列表可见,可手动运行。

【问题现象】

  1. 守护脚本 wla_daemon.js 用 engines.execScriptFile() 调用同目录下的 douyin_follow.js,日志直接报:
    FileNotFoundException: 没有那个文件或目录
  2. 两个脚本都在Hamibot内部,文件名完全正确(无空格、大小写一致),手动运行正常。
  3. 但守护脚本就是“找不到”同目录脚本,必须把脚本放到 /sdcard/ 根目录才能被execScriptFile找到。

【关键日志】
(把你完整日志贴这里,尤其报错那几行)

【我的疑问】

  1. Hamibot 内部脚本的真实物理路径是什么?为什么同目录脚本execScriptFile找不到?
  2. engines.execScriptFile() 到底支持哪些路径?是否存在“虚拟目录/分组隔离”导致的路径不一致?
  3. 官方推荐:在Hamibot内部,通过脚本名直接调用的正确API是什么?(我查到有execScriptByName,但不确定是否官方推荐、是否稳定)

【我的诉求】请官方明确:

  • 同账号/同分组内,脚本之间互相调用的标准、稳定写法
  • 避免FileNotFoundException的正确路径配置或API用法
HAMI_6893877807 · 20 小时前
第 1 条补充
·
19 小时前

标题:后台守护脚本用 engines.execScript 调用子脚本,返回成功但子脚本完全不执行、不打印日志
内容:
我在做一个 “守护脚本 + 业务脚本” 的分离架构:
守护脚本(wla_daemon)在 Hamibot 前台正常运行,无障碍、后台弹出、自启动、省电白名单全部开了。
守护脚本通过:
javascript
运行
let engine = engines.execScript("douyin_follow.js", {
execArgv: { msgList: [], keywordRule: {} }
});
调用抖音业务脚本,返回值正常、不报任何错。
但 douyin_follow.js 完全不执行:
没有任何日志输出(连最开头的 console.show ()、log () 都不打印)
抖音完全不被拉起
子脚本像是 “被静默拦截” 了
单独直接运行 douyin_follow.js 是可以正常跑、正常拉起抖音、正常打印日志的。
我的环境:
手机:小米 Note 13 / MIUI 14
Hamibot:最新版
无障碍、后台弹出、悬浮窗、自启动、省电白名单全部已开启
想问:
engines.execScript 在前台守护脚本里调用另一个脚本,是否有什么限制?
为什么 execScript 返回成功,但子脚本完全不执行、不输出日志?
官方推荐的 “守护脚本调度业务脚本” 正确写法是什么?

回答

Hamibot AI
1
· 20 小时前

你遇到的 FileNotFoundException 是 Hamibot 脚本管理中非常典型的路径认知差异问题。核心原因在于 engines.execScriptFile() 的设计定位与 Hamibot 内部脚本的存储机制不匹配。下面为你逐一解答并提供标准写法。

1. Hamibot 内部脚本的真实物理路径是什么?为什么同目录调用会报错?

Hamibot 列表中的脚本并不以普通文件形式暴露在公共存储中。它们由 Hamibot 应用沙盒与云端同步机制统一管理,存储在应用私有目录或加密缓存中,路径是动态生成且受 Android 系统严格限制的。engines.execScriptFile() 底层依赖 java.io.File,只能识别 Android 文件系统的绝对物理路径。当你传入相对路径或脚本名时,引擎会在当前运行工作目录中查找文件,无法命中 Hamibot 内部管理的脚本,因此直接抛出 FileNotFoundException

2. engines.execScriptFile() 支持哪些路径?是否存在分组隔离?

  • 该 API 仅支持设备存储的绝对路径,例如 /sdcard/Scripts/douyin_follow.js 或通过 files.path('./douyin_follow.js') 转换后的完整路径。
  • Hamibot 的“账号/分组”是云端同步与管理界面的逻辑概念,并非文件系统的真实目录。脚本在本地没有按分组建立文件夹,因此不存在“同目录”的文件系统映射,也不支持通过相对路径互相调用。

3. 官方推荐的内部脚本调用 API 是什么?

在 Hamibot 内部互相调用脚本,标准且稳定的 API 是 engines.execScript(name[, config])。该接口专门用于运行 Hamibot 脚本列表中的脚本,引擎会自动通过脚本名称在本地缓存索引中定位并执行,完全避开物理路径问题。你提到的 execScriptByName 并非官方标准 API,请直接使用 engines.execScript()

✅ 同账号/分组内脚本互相调用的标准写法

// 文档地址 https://docs.hamibot.com/
// 守护脚本 wla_daemon.js 中调用业务脚本
var targetScriptName = 'douyin_follow.js'; // 必须与 Hamibot 列表中的名称完全一致(含后缀)
var config = {
    loopTimes: 1,
    interval: 0
};

var execution = engines.execScript(targetScriptName, config);
if (execution) {
    console.log('成功启动脚本: ' + targetScriptName);
} else {
    console.error('启动失败:未找到脚本,请检查名称是否完全匹配或脚本是否已同步到本地');
}

📌 关键注意事项与最佳实践

  • 名称严格匹配engines.execScript() 依赖脚本在 Hamibot 列表中的完整名称,区分大小写,必须包含 .js 后缀。
  • 同步状态:被调用的脚本必须在 Hamibot 客户端中可见(已同步到本地)。若脚本仅存在于云端未拉取,首次调用可能失败,建议在 Hamibot 界面手动运行一次或确保网络同步完成。
  • 独立运行环境:通过 engines.execScript() 启动的脚本会在新的独立环境中运行,不共享父脚本的全局变量。若需传递参数,推荐使用 storage 模块或本地文件读写。
  • 权限检查:若子脚本启动后立即提示“运行结束”,请进入手机设置确认已开启 Hamibot 的无障碍服务,并授予“后台弹出界面”、“显示悬浮窗”及“自启动/后台启动”权限(MIUI 系统对后台限制较严,需手动放行)。
  • 引擎兼容性:Hamibot 使用 Rhino 1.7.15 引擎,示例已避免箭头函数与默认参数,确保在 Android 13/MIUI 14 环境下稳定执行。

使用 engines.execScript() 替换 execScriptFile() 即可彻底解决路径找不到问题,并符合 Hamibot 云端脚本管理的架构设计。如有参数传递或跨脚本状态同步的具体场景,可提供细节,我会为你补充对应方案。

ℹ️ 内容由 AI 生成,可能不准确,请注意核实
Hamibot AI
1
· 18 小时前

你遇到的“返回成功但子脚本静默不执行”是 MIUI 14 后台限制与 Hamibot 引擎特性叠加导致的典型现象。engines.execScript 返回对象仅表示引擎创建与任务派发成功,不代表子脚本已完整运行。下面逐条解答并提供标准调度方案。

1. engines.execScript 在守护脚本中调用是否有限制?

引擎层面没有限制,支持任意脚本互相调用。但受 Android 10+ 及 MIUI 14 系统策略影响,后台上下文启动的脚本在创建 UI、悬浮窗或拉起其他应用时会被严格拦截。若子脚本包含 console.show() 或强依赖前台权限的操作,系统会直接终止该引擎进程,表现为“静默退出”。

2. 为什么返回成功但子脚本不执行、不打印日志?

  • 配置参数写法错误engines.execScript 的 config 对象不支持 execArgv 字段。传入无效键值会被忽略,但子脚本若通过 engines.myEngine().execArgv 读取参数会得到 undefined,若开头有强依赖逻辑会直接抛出异常退出。
  • console.show() 导致静默崩溃:后台调度的脚本调用 console.show() 在 MIUI 上极大概率失败。若未包裹 try-catch,脚本会在首行直接崩溃,后续 log() 与抖音拉起逻辑均不会执行。
  • 日志不可见误区:后台引擎的 log() 输出默认写入 Hamibot 内部日志缓冲,不会自动弹出控制台。你看到的“不打印日志”通常是控制台创建失败,而非脚本未运行。
  • 应用拉起拦截:MIUI 的“后台弹出界面”与“链式启动”限制会拦截 launchApp(),需配合包名启动或确保权限完整放行。

3. 官方推荐的“守护脚本调度业务脚本”标准写法

使用 engines.execScript() 配合 storages 传参,移除子脚本中的 console.show(),并增加异常捕获与 MIUI 兼容启动逻辑。

守护脚本(wla_daemon.js)

// 文档地址 https://docs.hamibot.com/
var storage = storages.create('wla_daemon');
storage.put('msgList', []);
storage.put('keywordRule', {});

var targetName = 'douyin_follow.js';
var execution = engines.execScript(targetName, {
    loopTimes: 1,
    interval: 0
});

if (execution) {
    log('已派发任务: ' + targetName);
} else {
    log('任务派发失败,请检查脚本名称或同步状态');
}

业务脚本(douyin_follow.js)

// 文档地址 https://docs.hamibot.com/
try {
    // 后台调度脚本严禁使用 console.show(),MIUI 会拦截悬浮窗创建导致静默崩溃
    // 所有日志请通过 Hamibot 客户端「运行日志」查看
    log('douyin_follow.js 开始执行');

    var storage = storages.create('wla_daemon');
    var msgList = storage.get('msgList', []);
    var keywordRule = storage.get('keywordRule', {});
    log('读取参数成功: ' + JSON.stringify(keywordRule));

    // MIUI 兼容的抖音拉起方式
    var launched = launchApp('抖音');
    if (!launched) {
        log('名称拉起失败,尝试包名启动');
        app.startActivity({
            packageName: 'com.ss.android.ugc.aweme',
            className: 'com.ss.android.ugc.aweme.main.MainActivity'
        });
    }
    log('抖音已拉起,执行业务逻辑');
    // 你的业务代码...
} catch (e) {
    log('douyin_follow.js 运行异常: ' + e);
}

📌 关键排查与最佳实践

  • 彻底移除 console.show():守护/后台调度的子脚本绝对不要使用该方法。MIUI 会直接拦截导致脚本首行崩溃。调试期可用 files.write('/sdcard/hamibot_debug.log', new Date() + ' started\n', true); 验证脚本是否真正进入执行阶段。
  • 正确传参方式engines.execScript 不支持 execArgv 配置。跨脚本数据传递统一使用 storages 模块或本地文件,稳定且兼容所有 Android 版本。
  • MIUI 14 权限复核:设置 → 应用设置 → Hamibot → 权限管理,确保开启:后台弹出界面显示悬浮窗自启动省电策略-无限制。开发者选项中关闭“暂停执行后台应用”。
  • 日志查看路径:子脚本的 log() 输出不会实时弹窗,请打开 Hamibot 客户端 → 底部「我的」→ 「运行日志」查看完整输出。
  • 引擎兼容性:示例已适配 Rhino 1.7.15,避免箭头函数与默认参数,确保在 Android 13 环境下稳定执行。

按上述结构替换后,子脚本即可正常被调度并执行。若 /sdcard/hamibot_debug.log 仍未生成,请检查 Hamibot 列表中 douyin_follow.js 的名称是否包含隐藏空格或特殊字符,并确保脚本已点击“同步”至本地。需要进一步定位可提供日志文件生成结果或 Hamibot 运行日志截图。

ℹ️ 内容由 AI 生成,可能不准确,请注意核实