Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Execute Python Code in QM Using python.net
#18
Converted to C# 6. Fixed newlines.
But with `import win32print` throws error `PythonEngine is not initialized`. Don't know why.
Note, I changed the searchDirs path and the dll path.

Macro Macro3510
Code:
Copy      Help
/exe
out

CsScript x
str Opt=
;searchDirs=C:\LA workspace\.nuget\PyNet
;references=System.Core;Python.Runtime.dll;Microsoft.CSharp;netstandard
;compilerOptions=/warn:1
x.SetOptions(Opt 1)

x.AddCode("")
str code=
;###pywin32
;import ctypes
;print("hello world from python!")
;print("goodbye!")

x.Call("Pynet.pyCall" code)
;
;import win32print
;print(win32print.__file__)
;
;default_printer = win32print.GetDefaultPrinter()
;print(default_printer)


;BEGIN PROJECT
;main_function  Macro3510
;exe_file  $my qm$\Macro3510.qmm
;flags  6
;guid  {E66B3D29-E971-42A1-A722-B304704DB56D}
;END PROJECT

#ret
using System;
using System.IO;
using System.Diagnostics;
using System.Reflection;
using System.Linq;
using Python.Runtime;
using System.Collections;
using System.Collections.Generic;

public class Pynet : IDisposable
{
,Py.GILState _gil;
,PyModule _m;
,bool _shutdown;

,public static object pyCall(string code)
,{
,,,using (var pyn = new Pynet())
,,,{
,,,,pyn.Module.Exec(code);
,,,,return null;
,,,}
,}

,/// <summary>
,/// Initializes the Python engine and optionally adds code.
,/// </summary>
,/// <param name="code">If not null/"", calls <b>PyModule.Exec</b>.</param>
,/// <param name="enablePrint">Redirect the output of the Python's print function to console. Default true.</param>
,public Pynet(string code = null, bool enablePrint = true)
,{
,,if (!PythonEngine.IsInitialized)
,,{
,,,Runtime.PythonDLL = @"C:\Program Files (x86)\Python313-32\python313.dll";

,,,PythonEngine.Initialize();
,,,_shutdown = true;
,,}
,,_gil = Py.GIL();

,,if (enablePrint)
,,{
,,,Module.Exec("import sys\nclass NetConsole(object):\n    def __init__(self, writeCallback):\n        self.writeCallback = writeCallback\n\n    def write(self, message):\n        self.writeCallback(message)\n\n    def flush(self):\n        pass\n\ndef setConsoleOut(writeCallback):\n    sys.stdout = NetConsole(writeCallback)\n");
,,,Action<string> writer = (string s) => { if(!(s=="\r" || s=="\n")) Console.Write(s); };
,,,Module.InvokeMethod("setConsoleOut", Python.Runtime.PyObject.FromManagedObject(writer));
,,}

,,if (!string.IsNullOrEmpty(code)) Module.Exec(code);
,}

,/// <summary>
,/// Unlocks/disposes Python objects and shuts down the engine.
,/// </summary>
,public void Dispose()
,{
,,if(_m!=null) _m.Dispose();
,,if(_gil!=null) _gil.Dispose();
,,if (_shutdown)
,,{
,,,try { PythonEngine.Shutdown(); } //without this the process does not exit
,,,catch (System.Runtime.Serialization.SerializationException) { } //thrown when using enablePrint
,,,//.NET 9+: BinaryFormatter serialization and deserialization have been removed
,,,//catch (PlatformNotSupportedException) { }
,,}
,}

,/// <summary>
,/// Gets the result of <b>Py.CreateScope</b>.
,/// You can assign it to a <c>dynamic</c> variable and call functions defined in your Python code.
,/// </summary>
,public PyModule Module { get { if(_m==null) _m = Py.CreateScope(); return _m; } }
}


Messages In This Thread
RE: Execute Python Code in QM Using python.net - by Gintaras - 06-09-2025, 03:01 PM
RE: First steps with Python.NET - by Davider - 06-09-2025, 03:30 AM

Forum Jump:


Users browsing this thread: 1 Guest(s)