5.0 KiB
Macros, Loading, and Running Scripts
Command Macros (no script needed)
A macro is a string of command-line input. Anywhere Rhino accepts a command (alias, toolbar button, _ReadCommandFile), you can place a macro.
Syntax rules
| Token | Meaning |
|---|---|
! |
Cancel any currently running command before this one starts. Always start macros with !. |
_ |
Use the English (invariant) command name, so the macro works in any locale. |
- |
Run the command in script mode — suppress dialogs, accept input from the macro string. |
_Enter |
Press Enter at the current prompt. |
Pause |
Stop and wait for the user to supply this input interactively. |
; |
Comment to end of line. |
| Newline | Same as a space — a separator between tokens, not a command terminator. |
Example macros
! _-Line 0,0,0 10,0,0
! _-Circle 0,0,0 5 _Enter
! _SelAll _Delete
! _-Properties _Object _Name "MyObject" _EnterEnd _Enter
! _-RunPythonScript "MyScript.py"
Running Saved Scripts
Python (.py)
_-RunPythonScript "C:\Users\example\Scripts\MyScript.py"
Or, with the script folder on the search path:
_-RunPythonScript "MyScript.py"
_EditPythonScript opens the legacy editor; _ScriptEditor (Rhino 8) opens the unified editor with Python 3, VB, and C#.
RhinoScript (.rvb, .vbs)
Two steps: load the file (registers its subs/functions), then run a named sub.
_-LoadScript "MyScript.rvb"
_-RunScript MyMainSub
A single .rvb can hold many subs; _RunScript chooses which to invoke.
Search Paths
Options → Files → Search paths — folders listed here are scanned when you reference a script by bare filename. Without this, you must give a full path.
Startup Scripts
Options → RhinoScript → Startup (and Options → Python → Startup) — files in these lists run once when Rhino opens. Useful for registering custom commands or aliases.
Guard against missing document in startup code:
import scriptcontext as sc
def startup():
if sc.doc is None:
return
startup()
Toolbar Buttons & Aliases
A toolbar button’s Command field is just a macro. To make a button that runs your script:
! _-RunPythonScript "MyScript.py"
Set the Tooltip to a short description; set the icon via the button editor.
To create an alias: Options → Aliases → New. The alias name becomes a typed command; its value is the macro.
Invoking Macros From a Script
import rhinoscriptsyntax as rs
rs.Command("! _-Line 0,0,0 10,0,0", echo=False)
echo=False suppresses command-history output but does not suppress prompts — always use - and complete every prompt within the macro string.
rhinocode CLI (Rhino 8)
rhinocode is the Rhino 8 command-line tool for running scripts and commands against a running Rhino instance from an external terminal.
Basic commands
rhinocode script "C:\path\to\MyScript.py" # run a Python script
rhinocode command "_Circle 0,0,0 5 _Enter" # run a Rhino command
rhinocode --rhino <instance-id> script "MyScript.py" # target a specific instance
<instance-id> looks like rhinocode_remotepipe_75029. Find the ID in Rhino's title bar or
by running StartScriptServer in Rhino, which prints the pipe name to the command line.
Architecture — pipe server
rhinocode does not spawn a new Rhino process. It connects to a persistent server that Rhino
exposes (StartScriptServer). Scripts execute inside that server process, which means:
- Environment variables are isolated. Variables set in the calling shell (
set FOO=bar) are NOT visible inside the script viaos.environ. The server was started before your shell. os.getcwd()is the server's working directory, not the directory you called rhinocode from. Do not rely on it for output paths; pass the path explicitly.print()output IS piped back to the calling terminal — use it freely for status messages.
Passing data into a script
rhinocode does not support positional arguments after the script path — any extra tokens are concatenated onto the file URI, causing a "file does not exist" error. Workarounds:
| Channel | How | Notes |
|---|---|---|
| Temp file | Caller writes a file to a known location; script reads and deletes it. | Use a path derived from __file__ (see below), not %TEMP% — the server may resolve a different temp dir. |
| Rhino dialog | Script calls rhinoscriptsyntax.ListBox / GetString |
Always works; user sees a prompt in Rhino. |
__file__ is a URI
When running via rhinocode, __file__ is set as a file:/// URI with URL-encoded characters
(spaces become %20). Decode it before using it as a filesystem path:
import os, sys, urllib.parse
def _script_dir():
raw = __file__
if raw.startswith("file:///"):
raw = urllib.parse.unquote(raw[len("file:///"):])
if sys.platform == "win32":
raw = raw.replace("/", os.sep)
return os.path.dirname(os.path.abspath(raw))