Overview
One of the most common questions asked by new plugin developers is how to run, or script, existing Rhino commands from a plugin command. Rhino doesn’t allow plugin commands to run other commands except under very special circumstances.
Here’s the issue: If you have a command that is modifying the run-time database, and you run another command, problems can happen.
To work around this, the Rhino C/C++ SDK provides a special kind of command called a script command. You can create a script command as follows…
How To
Derive your command class from CRhinoScriptCommand instead of CRhinoCommand. In other words, instead of defining your command class like this:
class CCommandTest : public CRhinoCommand
Define your command class like this:
class CCommandTest : public CRhinoScriptCommand
Then, from within your command class’s RunCommand() member, you can call CRhinoApp::RunScript() to script the running of a Rhino command.  For example:
CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context )
{
  RhinoApp().RunScript( L"_-Line 0,0,0 10,10,10", 0 );
  return CRhinoCommand::success;
}
Warning
This kind of command can be very dangerous. Please be sure you understand the following:
- If you are not very familiar with how C++ references work, you should only call 
CRhinoApp::RunScript()from within aCRhinoScriptCommandderived command. - If you are very familiar with C++ references, then please observe the following rules:
- If you get a reference or pointer to any part of the Rhino run-time database, this reference or pointer will not be valid after you call 
CRhinoApp::RunScript(). - If you get a reference or a pointer, then call 
CRhinoApp::RunScript(), and then use the reference, Rhino will probably crash. - All pointers and references used by the command should be scoped such that they are only valid for the time between calls to 
CRhinoApp::RunScript(). 
 - If you get a reference or pointer to any part of the Rhino run-time database, this reference or pointer will not be valid after you call 
 
This is because CRhinoApp::RunScript() can change the dynamic arrays in the run-time database.  The result is that all pointers and references become invalid. Be sure to scope your variables between CRhinoApp::RunScript() calls.
NOTE: In a normal command, when the user enters a command beginning with a !, the command exits. There is no documented way to get this behavior from within a script command.
Sample
Here’s good scoping practice when your command is a script command.
CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context )
{
  {
    section A
    ... do some stuff ...
  }
  RhinoApp().RunScript(...);
  {
    section B
    ... do some stuff ...
  }
  RhinoApp().RunScript(...);
  {
    section C
    ... do some stuff ...
  }
  RhinoApp().RunScript(...);
  {
    section D
    ... do some stuff ...
  }
  RhinoApp().RunScript(...);
  {
    section E
    ... do some stuff ...
  }
  return CRhinoCommand::success;
}
Never allow references and pointers from one section to be used in another section.
