Example #1
0
        /// Run the script and print the output to a new output window.
        public int ExecuteScript(string sourcePath, string syspaths, string cmdName,
                                 bool forcedDebugMode, bool altScriptMode)
        {
            try
            {
                // Setup engine and set __file__
                var engine = CreateEngine();
                var scope  = SetupEnvironment(engine);

                // Get builtin scope to add custom variables
                var builtin = IronPython.Hosting.Python.GetBuiltinModule(engine);
                // add engine to builtins
                builtin.SetVariable("__ipyengine__", engine);
                // add command path to builtins
                builtin.SetVariable("__commandpath__", Path.GetDirectoryName(sourcePath));
                builtin.SetVariable("__commandname__", cmdName);                    // add command name to builtins
                builtin.SetVariable("__forceddebugmode__", forcedDebugMode);        // add forced debug mode to builtins
                builtin.SetVariable("__shiftclick__", altScriptMode);               // set to true of alt script mode

                // Add assembly's custom attributes
                builtin.SetVariable("__assmcustomattrs__", typeof(ScriptExecutor).Assembly.CustomAttributes);

                var scriptOutput = new ScriptOutput();  // New output window
                var hndl         = scriptOutput.Handle; // Forces creation of handle before showing the window
                scriptOutput.Text = cmdName;            // Set output window title to command name
                builtin.SetVariable("__window__", scriptOutput);

                // Create output stream
                var outputStream = new ScriptOutputStream(scriptOutput);

                // Process search paths provided to constructor
                // syspaths variable is a string of paths separated by ';'
                // Split syspath and update the search paths with new list
                engine.SetSearchPaths(syspaths.Split(';'));

                // Setup IO streams
                engine.Runtime.IO.SetOutput(outputStream, Encoding.UTF8);
                engine.Runtime.IO.SetErrorOutput(outputStream, Encoding.UTF8);
                engine.Runtime.IO.SetInput(outputStream, Encoding.UTF8);

                scope.SetVariable("__file__", sourcePath);

                var script = engine.CreateScriptSourceFromFile(sourcePath, Encoding.UTF8, SourceCodeKind.Statements);

                // 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;


                // 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
                    outputStream.WriteError(string.Join("\n",
                                                        ExternalConfig.ipyerrtitle,
                                                        string.Join("\n", errors.Errors.ToArray())));
                    _message = "";
                    return((int)Result.Cancelled);
                }


                // Finally let's execute
                try
                {
                    script.Execute(scope);

                    _message = (scope.GetVariable("__message__") ?? "").ToString();
                    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("\n", ExternalConfig.ipyerrtitle, _ipy_err_messages);
                    _dotnet_err_message = string.Join("\n", ExternalConfig.dotneterrtitle, _dotnet_err_message);

                    outputStream.WriteError(_ipy_err_messages + "\n\n" + _dotnet_err_message);
                    _message = "";
                    return((int)Result.Cancelled);
                }
            }
            catch (Exception ex)
            {
                _message = ex.ToString();
                return((int)Result.Failed);
            }
        }