06-09-2025, 03:01 PM
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
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
/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; } }
}