I am creating an IronPython engine more or less like so:
var engine = IronPython.Hosting.Python.CreateEngine();
var scope = engine.CreateScope();
// my implementation of System.IO.Stream
var stream = new ScriptOutputStream(engine);
engine.Runtime.IO.SetOutput(stream, Encoding.UTF8);
engine.Runtime.IO.SetErrorOutput(stream, Encoding.UTF8);
engine.Runtime.IO.SetInput(stream, Encoding.UTF8);
var script = engine.CreateScriptSourceFromString(source, SourceCodeKind.Statements);
script.Execute(scope);
The variable source
is a string with following contents (python statements):
import code
code.interact(None, None,
{
'__name__' : '__console__',
'__doc__' : None,
})
The stream is being hosted on a windows form. When that form closes, I want the interpreter to quit. Obviously, I tried closing the stream in the Read
method:
/// <summary>
/// Read from the _inputBuffer, block until a new line has been entered...
/// </summary>
public override int Read(byte[] buffer, int offset, int count)
{
if (_gui.IsDisposed)
{
return 0; // msdn says this indicates the stream is closed
}
while (_completedLines.Count < 1)
{
// wait for user to complete a line
Application.DoEvents();
Thread.Sleep(10);
}
var line = _completedLines.Dequeue();
return line.Read(buffer, offset, count);
}
The member variable _completedLines
holds a queue of MemoryStream
objects representing lines the user has entered so far. _gui
is a reference to the windows form - when it is disposed, I somehow want the IronPython engine to stop executing code.interact()
.
Returnin 0
from the Read
method does not work (Read
is just called again). Raising one of the exceptions from the documentation of Read does not work either: It does stop execution of the interpreter, but the IDE breaks inside the Read
method :(
I have also tried returning ^Z
(0x1a) and ^D
(0x04) in Read
's buffer, as these are used on the console to quit the interpreter, but that doesn't work at all...