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+ 中执行时,会触发以下级联失败:- 调用
File.expand_path(__FILE__).untaint→NoMethodError(Ruby 3.0+ 彻底删除该方法) - 后续
require_relative 'sm2/core'因路径对象未“净化”而被沙箱拦截 →LoadError - 整个插件命名空间(
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 工具链团队,建议建立如下规范:
- 插件发布必须声明
Ruby Runtime Matrix(如:SM3.2 supports Ruby 3.0–3.2, SU2023–2025) - 构建阶段集成
ruby -c静态语法检查 +rubocop --only Rails/Output规避不安全 I/O - 设立
legacy-support分支专用于 SU2022 及以下客户,主干(main)仅维护 Ruby 3.x 兼容代码
十、延伸层:同类问题泛化模式与行业启示
此问题非孤例,而是桌面端嵌入式脚本引擎演进的共性挑战:
- Adobe ExtendScript → UXP 迁移中
FileAPI 权限收紧 - Revit Python Shell(RPS)从 IronPython 2.7 升级至 3.x 后
sys.path沙箱隔离 - 根本解法一致:放弃运行时修补,转向语义化版本控制 + 自动化兼容性验证流水线
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 调用