示例#1
0
        public ScriptScope CreateScope(ScriptEngine engine, ref RMSCmdExecutorCommand rmsCmd)
        {
            var scope = IronPython.Hosting.Python.CreateModule(engine, "__main__");

            SetupScope(engine, scope, ref rmsCmd);

            return(scope);
        }
示例#2
0
        public void SetupScope(ScriptEngine engine, ScriptScope scope, ref RMSCmdExecutorCommand rmsCmd)
        {
            // BUILTINS -----------------------------------------------------------------------------------------------
            // Get builtin to add custom variables
            var builtin = IronPython.Hosting.Python.GetBuiltinModule(engine);

            // Add current IronPython engine to builtins
            builtin.SetVariable("__ipyengine__", engine);

            // Adding output window handle (__window__ is for backwards compatibility)
            builtin.SetVariable("__window__", rmsCmd.OutputWindow);
            builtin.SetVariable("__output__", rmsCmd.OutputWindow);

            // Adding output window stream
            builtin.SetVariable("__outputstream__", rmsCmd.OutputStream);

            // Add host application handle to the builtin to be globally visible everywhere
            builtin.SetVariable("__revit__", _revit);

            // Add handles to current document and ui document
            if (_revit.ActiveUIDocument != null)
            {
                builtin.SetVariable("__activeuidoc__", _revit.ActiveUIDocument);
                builtin.SetVariable("__activedoc__", _revit.ActiveUIDocument.Document);
                builtin.SetVariable("__zerodoc__", false);
            }
            else
            {
                builtin.SetVariable("__activeuidoc__", (Object)null);
                builtin.SetVariable("__activedoc__", (Object)null);
                builtin.SetVariable("__zerodoc__", true);
            }

            // Add this script executor to the the builtin to be globally visible everywhere
            // This support pyrevit functionality to ask information about the current executing command
            builtin.SetVariable("__externalcommand__", rmsCmd);

            // Adding data provided by IExternalCommand.Execute
            builtin.SetVariable("__commanddata__", rmsCmd.CommandData);
            builtin.SetVariable("__elements__", rmsCmd.SelectedElements);

            builtin.SetVariable("__commandpath__", Path.GetDirectoryName(rmsCmd.ScriptSourceFile));
            builtin.SetVariable("__debugmode__", rmsCmd.DebugMode);

            // SCOPE --------------------------------------------------------------------------------------------------
            // Add command info to builtins
            scope.SetVariable("__file__", rmsCmd.ScriptSourceFile);
            scope.SetVariable("__result__", (int)Result.Succeeded);
            scope.SetVariable("__modelname__", rmsCmd.ModelName);
            scope.SetVariable("__outputpath__", rmsCmd.OutputPath);
            scope.SetVariable("__outputprefix__", rmsCmd.OutputPrefix);
        }
示例#3
0
        public int ExecuteScript(RMSCmdExecutorCommand rmsCmd)
        {
            // Get engine and setup
            var engine = CreateEngine();
            var scope  = CreateScope(engine, ref rmsCmd);

            // Add script directory address to sys search paths
            var path = engine.GetSearchPaths();

            path.Add(System.IO.Path.GetDirectoryName(rmsCmd.ScriptSourceFile));

            if (!rmsCmd.GuiMode)
            {
                foreach (var search_path in rmsCmd.ModuleSearchPaths)
                {
                    path.Add(search_path);
                }
            }
            else
            {
                path.Add(GetCommandServicesModulePath());
            }


            engine.SetSearchPaths(path);

            // Add output streams
            engine.Runtime.IO.SetOutput(rmsCmd.OutputStream, Encoding.UTF8);
            engine.Runtime.IO.SetErrorOutput(rmsCmd.OutputStream, Encoding.UTF8);

            // setting module to be the main module so __name__ == __main__ is True
            var compiler_options = (PythonCompilerOptions)engine.GetCompilerOptions(scope);

            compiler_options.ModuleName = "__main__";
            compiler_options.Module    |= IronPython.Runtime.ModuleOptions.Initialize;

            // Create the script from source file
            var script = engine.CreateScriptSourceFromFile(rmsCmd.ScriptSourceFile, Encoding.UTF8, SourceCodeKind.Statements);

            // Setting up error reporter and compile the script
            var errors  = new ErrorReporter();
            var command = script.Compile(compiler_options, errors);

            // Process compile errors if any
            if (command == null)
            {
                // compilation failed, print errors and return
                rmsCmd.OutputStream.WriteError(string.Join("\r\n", "IronPython Traceback:",
                                                           string.Join("\r\n", errors.Errors.ToArray())));
                return((int)Result.Cancelled);
            }


            try
            {
                script.Execute(scope);
                return((int)(scope.GetVariable("__result__") ?? Result.Succeeded));
            }
            catch (SystemExitException)
            {
                // ok, so the system exited. That was bound to happen...
                return((int)Result.Succeeded);
            }
            catch (Exception exception)
            {
                // show (power) user everything!
                string _dotnet_err_message = exception.ToString();
                string _ipy_err_messages   = engine.GetService <ExceptionOperations>().FormatException(exception);

                // Print all errors to stdout and return cancelled to Revit.
                // This is to avoid getting window prompts from Revit.
                // Those pop ups are small and errors are hard to read.
                _ipy_err_messages   = string.Join("\r\n", "IronPython Traceback:", _ipy_err_messages);
                _dotnet_err_message = string.Join("\r\n", "Script Executor Traceback:", _dotnet_err_message);

                rmsCmd.OutputStream.WriteError(_ipy_err_messages + "\r\n\r\n" + _dotnet_err_message);
                return((int)Result.Cancelled);
            }
            finally
            {
                if (rmsCmd.LogFile != null)
                {
                    AppendToLog(rmsCmd.LogFile, rmsCmd.OutputWindow.GetContents());
                }
            }
        }