hitomo 2026-02-28 02:40 采纳率: 98.6%
浏览 0
已采纳

SM2.1.1插件加载失败,提示“Ruby script error”如何解决?

SM2.1.1插件加载失败并报“Ruby script error”,常见于SketchUp 2023+版本(尤其是v2024/v2025)中因Ruby环境变更导致的兼容性问题。根本原因:SM2.1.1基于旧版Ruby 2.7 API开发,而新版SketchUp默认搭载Ruby 3.0+,其废弃了`Object#taint`/`untaint`等方法,并强化了沙箱安全策略,致使插件初始化脚本(如`sm2.rb`或`init.rb`)在解析时抛出`NoMethodError`或`SecurityError`。典型表现包括插件菜单不显示、控制台报错“undefined method `untaint' for #”。解决路径分三步:①确认SketchUp版本与SM官方支持矩阵(SM2.1.1仅官方支持至SU2022);②临时降级方案:修改插件主文件,移除所有`taint`/`untaint`调用,并将`require_relative`替换为`require`以规避路径解析异常;③推荐升级至SM官方维护的SM3.x系列(已适配Ruby 3.x)。切勿强行启用`$SAFE=0`——该方式在SU2023+已被彻底移除,无效且危险。
  • 写回答

1条回答 默认 最新

  • 爱宝妈 2026-02-28 02:41
    关注
    ```html

    一、现象层:典型错误表征与日志捕获

    在 SketchUp 2024/2025 中启用 SM2.1.1 后,控制台(Ruby Console)高频输出:NoMethodError: undefined method `untaint' for #<String:0x000001a2b3c4d5e6>SecurityError: Insecure operation - untaint。插件菜单栏完全缺失,Plugins → SmartTools 不可见,且 SketchUp.find_support_file("Plugins/sm2") 返回 nil,表明加载阶段即中断。

    二、定位层:版本兼容性矩阵与 Ruby 运行时差异分析

    SketchUp 版本Ruby 版本SM2.1.1 官方支持关键废弃 API
    SU2022 及更早Ruby 2.7.6✅ 全面支持taint/untaint, $SAFE 模式有效
    SU2023+Ruby 3.0.2+(嵌入式)❌ 明确不支持taint 系列方法被移除;$SAFE=0 被硬编码禁用;require_relative 路径解析受沙箱严格限制

    三、根因层:Ruby 3.x 安全模型演进与插件初始化链断裂

    SM2.1.1 的 init.rb 在 SU2023+ 中执行时,会触发以下级联失败:

    1. 调用 File.expand_path(__FILE__).untaintNoMethodError(Ruby 3.0+ 彻底删除该方法)
    2. 后续 require_relative 'sm2/core' 因路径对象未“净化”而被沙箱拦截 → LoadError
    3. 整个插件命名空间(SmartTools)未注册,导致 UI.menu('Plugins').add_item 永远不会执行

    四、验证层:快速诊断脚本(可直接粘贴至 Ruby Console)

    # 执行后返回 true 表示处于 Ruby 3.x 环境且 taint 已失效
    def ruby3_taint_broken?
      begin
        "".untaint
        false
      rescue NoMethodError
        true
      rescue SecurityError
        true
      end
    end
    puts "Ruby 3.x taint broken: #{ruby3_taint_broken?}"
    puts "SU Version: #{SketchUp.version}"
    puts "Ruby Version: #{RUBY_VERSION}"
    

    五、解法层:三阶治理路径(含风险分级)

    graph TD A[问题识别] --> B{SU版本 ≤ 2022?} B -->|Yes| C[无需干预,检查安装路径] B -->|No| D[进入兼容性治理] D --> E[方案①:确认支持矩阵
    → 官方文档明确 SM2.1.1 最高支持 SU2022] D --> F[方案②:临时代码热修复
    → 删除所有 .taint/.untaint
    → 替换 require_relative 为 require + 绝对路径] D --> G[方案③:长期架构升级
    → 迁移至 SM3.2+(已通过 Ruby 3.1+ CI 测试)] F --> H[⚠️ 风险:需手动维护多版本分支,无自动更新机制] G --> I[✅ 推荐:SM3.x 采用 Module#autoload + Pathname 封装,完全规避沙箱路径异常]

    六、实践层:SM2.1.1 热修复操作指南(以 sm2.rb 为例)

    原始代码段(SU2022 兼容):

    root = File.expand_path(File.dirname(__FILE__)).untaint
    $:.unshift root.untaint
    require_relative 'sm2/core'
    

    修复后代码段(SU2024/2025 兼容):

    root = File.expand_path(File.dirname(__FILE__))
    $:.unshift root
    # 注意:require_relative 必须替换为 require,并确保文件名大小写精确匹配
    require 'sm2/core'
    

    七、规避层:已被证实无效的“伪解决方案”清单

    • $SAFE = 0 —— SU2023+ 中该全局变量被置为只读,赋值即抛 RuntimeError
    • 修改 SketchUp.exe 的 manifest 强制降级 Ruby —— 加载器校验签名失败,启动崩溃
    • 将插件拖入旧版 SU2022 的 Plugins 文件夹再复制到新版本 —— Ruby 字节码缓存(.rbc)不兼容,仍报错

    八、演进层:SM3.x 的现代化适配设计要点

    SM3.2 引入的关键变更包括:

    • 使用 Pathname.new(__dir__).join('core.rb') 替代字符串路径拼接
    • 核心模块采用 autoload :Core, 'sm3/core' 延迟加载,绕过初始化期沙箱检查
    • 所有外部资源(图标、配置)通过 SketchUp.find_support_file 标准接口获取,符合 SU 安全策略
    • CI 流水线覆盖 Ruby 3.0/3.1/3.2 + SU2023/SU2024/SU2025 全组合自动化测试

    九、治理层:企业级插件生命周期管理建议

    针对 BIM/CAD 工具链团队,建议建立如下规范:

    1. 插件发布必须声明 Ruby Runtime Matrix(如:SM3.2 supports Ruby 3.0–3.2, SU2023–2025)
    2. 构建阶段集成 ruby -c 静态语法检查 + rubocop --only Rails/Output 规避不安全 I/O
    3. 设立 legacy-support 分支专用于 SU2022 及以下客户,主干(main)仅维护 Ruby 3.x 兼容代码

    十、延伸层:同类问题泛化模式与行业启示

    此问题非孤例,而是桌面端嵌入式脚本引擎演进的共性挑战:

    • Adobe ExtendScript → UXP 迁移中 File API 权限收紧
    • Revit Python Shell(RPS)从 IronPython 2.7 升级至 3.x 后 sys.path 沙箱隔离
    • 根本解法一致:放弃运行时修补,转向语义化版本控制 + 自动化兼容性验证流水线
    ```
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 3月1日
  • 创建了问题 2月28日