How do I pass arguments to a Python script with IronPython
Asked Answered
B

3

11

I have the following C# code where I call a python script from C#:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
using IronPython.Runtime;

namespace RunPython
{
    class Program
    {
        static void Main(string[] args)
        {
            ScriptRuntimeSetup setup = Python.CreateRuntimeSetup(null);
            ScriptRuntime runtime = new ScriptRuntime(setup);
            ScriptEngine engine = Python.GetEngine(runtime);
            ScriptSource source = engine.CreateScriptSourceFromFile("HelloWorld.py");
            ScriptScope scope = engine.CreateScope();
            source.Execute(scope);
        }
    }
}

I'm having trouble understanding each line of the code because my experience with C# is limited. How would I alter this code in order to pass a command line argument to my python script when I run it?

Bashemeth answered 21/5, 2015 at 21:36 Comment(1)
Possible duplicate of #5950235Poe
B
9

Thank you all for pointing me in the correct direction. For some reason engine.sys seems to no longer work for more recent versions of IronPython so instead GetSysModule must be used. Here is the revised version of my code that allows me to alter argv:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using IronPython.Runtime;

namespace RunPython
{
    class Program
    {
        static void Main(string[] args)
        {
            ScriptRuntimeSetup setup = Python.CreateRuntimeSetup(null);
            ScriptRuntime runtime = new ScriptRuntime(setup);
            ScriptEngine engine = Python.GetEngine(runtime);
            ScriptSource source = engine.CreateScriptSourceFromFile("HelloWorld.py");
            ScriptScope scope = engine.CreateScope();
            List<String> argv = new List<String>();
            //Do some stuff and fill argv
            argv.Add("foo");
            argv.Add("bar");
            engine.GetSysModule().SetVariable("argv", argv);
            source.Execute(scope);
        }
    }
}
Bashemeth answered 21/5, 2015 at 22:28 Comment(0)
M
4

"Command line arguments" exists only for processes. If you run code this way, you python script most likely will see arguments passed to your process when it was started (without Python code, it's hard to tell). As suggested in the comments, you can override command line arguments too.

If what you want to do is pass arguments, not necessarily command line arguments, then there're several approaches.

The most easy would be to add variables to the scope you've defined and read these variables in the script. For example:

int variableName = 1337;
scope.SetVariable("variableName", variableName);

In the python code, you'll have variableName variable.

Mccain answered 21/5, 2015 at 21:44 Comment(0)
P
2

While I think that @Discord's use of setting a variable would work, it would require some changing of sys.argvs to variableName.

Therefore, to answer the question, you should use engine.Sys.argv:

List<int> argv = new List<int>();
//Do some stuff and fill argv
engine.Sys.argv=argv;

References:

http://www.voidspace.org.uk/ironpython/custom_executable.shtml

How can I pass command-line arguments in IronPython?

Poe answered 21/5, 2015 at 21:50 Comment(2)
Thank you! One question I have regarding engine.Sys is that in my program I get a message stating the following: "'Microsoft.Scripting.Hosting.ScriptEngine' does not contain a definition for 'Sys' and no extension method 'Sys' accepting a first argument of type 'Microsoft.Scripting.Hosting.ScriptEngine' could be found (are you missing a using directive or assembly reference?)". How do I get this error to go away and get engine.Sys to be recognized?Bashemeth
Hmm.. I think the example was using a PythonRuntime instance. I'll need to poke around more.Poe

© 2022 - 2024 — McMap. All rights reserved.