0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OpenRCFとPythonを連携する方法

Last updated at Posted at 2025-06-14

本稿では,OpenRCFからPythonで書かれたコードを実行する方法について紹介します.後述する方法では,PythonのコードはPython用の一般的な実行エンジンで動かしつつ,OpenRCF側で入出力の差し替えとPythonコードを実行するタイミングの制御を行います.つまり,(内部的には)OpenRCFとPythonはそれぞれ独立して動作しているため,依存関係のバグが起こりにくい(or 起こらない)はずです.

1 準備

1.1 Pythonのインストール

普通にPythonをインストールします.ChatGPTなどに聞きながらやれば,問題なく完了するはずです.
https://www.python.org/downloads/
コマンドプロンプトで「python --version」と入力したときに,バージョンが表示されていればOKです.
image.png

1.2 Python用のフォルダとスクリプト(コード)を用意

まず,OpenRCFの「program」フォルダ内に「PythonScripts」というフォルダを新規作成します.フォルダの名前(PythonScripts)は重要なので,変更しないでください.
image.png
さらに,「PythonScripts」フォルダの中に「test_scripts.py」というファイルを作成します.
image.png
適当なエディタ(VS Codeなど)を用いて,test_scripts.pyに以下のようなサンプルコードを書きます.

import sys

a = int(sys.argv[1])  
b = int(sys.argv[2])  

print(a + b)

sys.argv[1], sys.argv[2]...がOpenRCF(C#)から受け取る値になります(不要な場合は無くてもOK).ここではint型としていますが,float型やdouble型にすることも可能です.また,python側でprintした文字列(ここでは a+b の値)は,OpenRCF(C#)側で読み込めるようになります.

1.3 OpenRCF側にPython用のクラス(C#)を用意

右クリック→「追加」→「新しい項目」で,「Python.cs」ファイルを作ります.
image.png
さらに,「Python.cs」ファイルに下記のコードを書きます(内容は理解せずに丸々コピペしてもOK).

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace OpenRCF
{
    class Python
    {
        private ProcessStartInfo processInfo = new ProcessStartInfo();
        
        public Python()
        {
            processInfo.UseShellExecute = false;
            processInfo.RedirectStandardOutput = true;
            processInfo.RedirectStandardError = true;
            processInfo.CreateNoWindow = true;

            string pathToPythonFolder = @"..\..\PythonScripts\";
            if (Directory.Exists(pathToPythonFolder)) processInfo.WorkingDirectory = pathToPythonFolder;
            else Console.WriteLine("Error : PythonScripts folder not found. Please create it.");

            string pathToPythonExe = @SearchPathToPythonExe();
            if(pathToPythonExe != null) processInfo.FileName = pathToPythonExe;
            else Console.WriteLine("Error : python.exe not found. Please install Python.");
        }

        private static string SearchPathToPythonExe()
        {
            string defaultPythonPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Programs", "Python");
            if (!Directory.Exists(defaultPythonPath)) return null;
            var basePathDirs = Directory.GetDirectories(defaultPythonPath);
            var pythonPathList = basePathDirs.Select(dir => Path.Combine(dir, "python.exe")).Where(File.Exists).ToList();
            if (pythonPathList.Any()) return pythonPathList[pythonPathList.Count - 1];
            else return null;
        }

        private static string ToString(object obj)
        {
            if (obj is Array innerArray && !(obj is string))
            {
                return string.Join(" ", innerArray.Cast<object>().Select(x => x.ToString()));
            }
            return obj.ToString();
        }

        public string Execute(string fileName, params object[] sysArgv)
        { 
            if (!fileName.EndsWith(".py")) fileName += ".py";
            if(!File.Exists(processInfo.WorkingDirectory + fileName))
            {
                Console.WriteLine("Error : {0} not found in the {1} directory.", fileName, processInfo.WorkingDirectory);
                return "";
            }
            processInfo.Arguments = fileName;
            if (0 < sysArgv.Length) processInfo.Arguments += " " + string.Join(" ", sysArgv.Select(obj => ToString(obj)));
            Process process = Process.Start(processInfo);
            string printedData = process.StandardOutput.ReadToEnd();
            string errorMsg = process.StandardError.ReadToEnd();
            process.WaitForExit();
            if (!string.IsNullOrWhiteSpace(errorMsg)) Console.WriteLine("Error : " + errorMsg);
            return printedData.Replace("\r\n", "");
        }
    }
}

以上で準備完了!

2 OpenRCFからPythonのコードを実行し,結果を取得する

2.1 Pythonクラスの使用例

OpenRCFの「MainWindow.xaml.cs」ファイルでの使用例は以下の通りです.

Python Python = new Python();

void Button1_Click(object sender, RoutedEventArgs e)
{
    string output = Python.Execute("test_script.py", 1, 2);
    Console.WriteLine(output);
}

ボタン1を押すと,test_script.pyファイルに引数(1, 2)を送り,その引数に対するPythonコードの実行結果(Pythonの中でprintしたもの)を受け取ることができます.つまり,python側で「sys.argv[1]=1」,「sys.argv[2]=2」としてコードを実行し,そのときにprint関数で出力したもの(3)がoutputに格納されてます.

2.2 補足

Python側に送るデータが多くなる場合は,以下のように配列で渡すこともできます.

Python Python = new Python();

void Button1_Click(object sender, RoutedEventArgs e)
{
    int[] input = new int[2] { 1, 2 };
    string output = Python.Execute("test_script.py", input);
    Console.WriteLine(output);
}

注意点としては,Python側(test_script.pyファイル)で引数(sys.argv[1], sys.argv[2]など)をfloat型やdouble型にしている場合は,OpenRCF(C#)もそれらの型に合わせて引数を与えてあげる必要があります.
また,もしpython側で引数(sys.argv[1], sys.argv[2]など)を使用していなかった場合は,以下のようにして実行できます.

Python Python = new Python();

void Button1_Click(object sender, RoutedEventArgs e)
{
    string output = Python.Execute("test_script.py");
    Console.WriteLine(output);
}

Pythonのコードを実行しているのはOpenRCFではなく,一般的なPythonの実行エンジンなので,何かPythonのライブラリを使用したい場合は,コマンドプロンプトの方で pip install すると使えるようになります.

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?