在32位程序中从C#运行Python函数(64位)

时间:2018-08-31 07:10:12

标签: c# python ironpython uipath

在对这个问题进行了很长时间的检查之后,我有点迷失了,我需要社区的帮助。首先让我解释一下这个问题:

我正在Windows 7(x64)中使用该软件(32位,称为UiPath)。从UiPath,我想通过使用Python 3.6(64位)解释器运行python方法。在UiPath中,您可以编写用C#编写的自己的活动。我的目标是编写活动(C#类),该活动将能够运行一些带参数的python函数,并向我返回此函数的输出(返回)。

我认为,cmd并不是一个好方法,也许IronPython可以帮助我,但是请您给我任何建议吗?

非常感谢您。

1 个答案:

答案 0 :(得分:0)

好的,我知道您说过要避免使用cmd,但是由于您基本上是在尝试从32位进程中执行64位进程,因此您总是不得不采取一种解决方法,之所以这样做,是因为它无法在进程中托管它。

我在此处创建了一个快速示例解决方案(Visual Studio 2017): https://github.com/Moobylicious/RunExternalProcessExample/archive/master.zip

这包含两个控制台项目-一个是64位的,另一个是32位的。 32位的代码通过创建进程来调用64位的代码(有效但隐藏的命令行)。然后显示它的输出。

如果仅按原样运行解决方案,则应运行32位控制台应用程序,它将调用64位控制台应用程序。

下面是运行外部进程的主要代码。样本中的版本是控制台应用程序的Main()方法,但是您可能必须将其放入类库中,或者将其放入满足特定需要的插件/活动/事物中。

public int RunProgram()
{
    //create  process to run an external program...
    System.Diagnostics.Process process = new System.Diagnostics.Process();
    System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
    //hide it - don't spawn a CMD window
    startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    startInfo.FileName = "cmd.exe";

    //add command line params - guess these would be passed in somehow?
    var arg1 = "function_name";
    var arg2 = "input1";
    var arg3 = "input2";

    //Build command line. 
    startInfo.Arguments = $@"/C c:\path\to\python\Some64BitProcess.exe {arg1} {arg2} {arg3}";

    //I don't know what the output of this will be.  whether it creates a file or 
    //just prints stuff out on the command line (STDOUT).  
    //it is possible to capture STDOUT into a stream, but for simplicity I'll simply re-direct it into
    //an output file via the command line '>' which will overwrite any file already there.
    startInfo.Arguments += " > output.txt";
    process.StartInfo = startInfo;

    //Run process
    process.Start();

    //wait for it to complete - note, if this process pauses for user input at 
    //any point this will basically just hang indefinitely.
    //you CAN pipe a 'Y' into it or something to avoid this(simulate a keypress), 
    //but would be better to work out command line
    //switches that supress any waiting for user input.
    process.WaitForExit();

    //now, we can get results.

    var output = File.ReadAllText("output.txt");

    //Do things with output?
    Console.WriteLine(output);
    Console.ReadLine();

    //process.ExitCode is the Exit Code of the command.  This might be useful as it might 
    //indicate specific errors encountered
    //by Python.
    return process.ExitCode;
}