# Call Python from C#
The documentation provides a sample implementation of the inter-process communication between C# and Python scripts.
# Python script to be called by C# application
import sys
import json
# load input arguments from the text file
filename = sys.argv[ 1 ]
with open( filename ) as data_file:
input_args = json.loads( data_file.read() )
# cast strings to floats
x, y = [ float(input_args.get( key )) for key in [ 'x', 'y' ] ]
print json.dumps( { 'sum' : x + y , 'subtract' : x - y } )
# C# code calling Python script
using MongoDB.Bson;
using System;
using System.Diagnostics;
using System.IO;
namespace python_csharp
{
class Program
{
static void Main(string[] args)
{
// full path to .py file
string pyScriptPath = "...../sum.py";
// convert input arguments to JSON string
BsonDocument argsBson = BsonDocument.Parse("{ 'x' : '1', 'y' : '2' }");
bool saveInputFile = false;
string argsFile = string.Format("{0}\\{1}.txt", Path.GetDirectoryName(pyScriptPath), Guid.NewGuid());
string outputString = null;
// create new process start info
ProcessStartInfo prcStartInfo = new ProcessStartInfo
{
// full path of the Python interpreter 'python.exe'
FileName = "python.exe", // string.Format(@"""{0}""", "python.exe"),
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = false
};
try
{
// write input arguments to .txt file
using (StreamWriter sw = new StreamWriter(argsFile))
{
sw.WriteLine(argsBson);
prcStartInfo.Arguments = string.Format("{0} {1}", string.Format(@"""{0}""", pyScriptPath), string.Format(@"""{0}""", argsFile));
}
// start process
using (Process process = Process.Start(prcStartInfo))
{
// read standard output JSON string
using (StreamReader myStreamReader = process.StandardOutput)
{
outputString = myStreamReader.ReadLine();
process.WaitForExit();
}
}
}
finally
{
// delete/save temporary .txt file
if (!saveInputFile)
{
File.Delete(argsFile);
}
}
Console.WriteLine(outputString);
}
}
}
# Remarks
Note that in the example above data is serialized using MongoDB.Bson library that can be installed via NuGet manager.
Otherwise, you can use any JSON serialization library of your choice.
Below are inter-process communication implementation steps:
BsonDocument argsBson = BsonDocument.Parse("{ 'x' : '1', 'y' : '2' }");
string argsFile = string.Format("{0}\\{1}.txt", Path.GetDirectoryName(pyScriptPath), Guid.NewGuid());
filename = sys.argv[ 1 ]
with open( filename ) as data_file:
input_args = json.loads( data_file.read() )
x, y = [ float(input_args.get( key )) for key in [ 'x', 'y' ] ]
print json.dumps( { 'sum' : x + y , 'subtract' : x - y } )
using (StreamReader myStreamReader = process.StandardOutput)
{
outputString = myStreamReader.ReadLine();
process.WaitForExit();
}
I am using the inter-process communication between C# and Python scripts in one of my projects that allows calling Python scripts directly from Excel spreadsheets.
The project utilizes ExcelDNA add-in for C# - Excel binding.
The source-code is stored in the GitHub repository (opens new window).
Below are links to wiki pages that provide an overview of the project and help to get started in 4 easy steps (opens new window).
- Getting Started (opens new window)
- Implementation Overview (opens new window)
- Examples (opens new window)
- Object-Wizard (opens new window)
- Functions (opens new window)
I hope you find the example and the project useful.