pythonnet engine is an invisible process. I execute #1 C# code in QM. The first execution is successful. However, the macro fails to terminate in the second execution, leading to QM crashing.
By using the Pynet class in the link below, the engine can exit properly. However, I am not sure how to add the following function to that class.
https://www.libreautomate.com/forum/show...5#pid36975
Another code! It would be fantastic if it could be added to the Pynet class.
By using the Pynet class in the link below, the engine can exit properly. However, I am not sure how to add the following function to that class.
https://www.libreautomate.com/forum/show...5#pid36975
Quote:public static object RunPythonCodeAndReturn(string pycode, object parameter, string parameterName, string returnedVariableName)
{
try
{
object returnedVariable = new object();
Initialize();
using (Py.GIL())
{
using (var scope = Py.CreateScope())
{
scope.Set(parameterName, parameter.ToPython());
scope.Exec(pycode);
returnedVariable = scope.Get<object>(returnedVariableName);
return returnedVariable;
}
}
}
catch (Exception)
{
throw;
}
}
Another code! It would be fantastic if it could be added to the Pynet class.
public dynamic? ExecuteScript<T>(string scriptFile, string className, string functionName, List<object> paramset)
{
T? result = default;
try
{
// Location of all the python scripts in the project. lets get the python file we are specifying in the function param
string file = $"{Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)}\\PythonScripts\\{scriptFile}.py";
// This is initalized in the program.cs, but just want to make sure it's initialized in case something happens
if (!PythonEngine.IsInitialized)
{
PythonEngine.Initialize();
Py.GIL();
}
using (var scope = Py.CreateScope())
{
// Our returned PythonObject from the python function call
PyObject? pythonReturn;
// Get the python file as raw text
string code = File.ReadAllText(file);
// Compile the code/file
var scriptCompiled = PythonEngine.Compile(code, file);
// Execute the compiled python so we can start calling it
scope.Execute(scriptCompiled);
// Lets get an instance of the class in python
PyObject pythonClass = scope.Get(className);
// Add parameters to the function?
if (paramset != null && paramset.Count > 0)
{
// This is an array of python parameters passed into a function
PyObject[] pyParams = new PyObject[paramset.Count];
// Loop through our incoming c# list of parameters and create PythonObject array .
for (int i = 0; i < paramset.Count; i++)
{
pyParams[i] = paramset[i].ToPython();
}
// Call the function on the class with parameters
pythonReturn = pythonClass.InvokeMethod(functionName, pyParams);
}
else // We aren't using parameters here
// Call the function on the class
pythonReturn = pythonClass.InvokeMethod(functionName);
// Lets convert our returned pythonObject to that of the object type (C#)
object? netObject = pythonReturn.AsManagedObject(typeof(object));
// A special case of when we want a list back. We will convert the object to the specific type in the caller function
if (typeof(T) == typeof(IList<object>))
{
object[] something = pythonReturn.As<object[]>();
return something;
}
// Convert the c# object to that of what we expect to be returned,. string/int/bool/class
if (netObject != null)
// convert the returned string to managed string object
result = (T)netObject;
}
return result;
}
catch (Exception)
{
// Handle your exceptions here
throw;
}
}