Hi Tim,
I modified your source to handle lisp arguments correctly, see the comments in the code.
I also commented out
this.Terminate();
This could potentially make cad crash because .net modules can’t be unloaded
/*
PyAcadDotNet.cs
Copyright (c) 2007, Tim Riley (riltim@gmail.com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
- Neither the name Tim Riley nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &AS IS& AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using AcEd = Autodesk.AutoCAD.EditorInput;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using IronPython.Hosting;
namespace PyAcadDotNet
{
public class AcadInterface : IExtensionApplication
{
static internal AcEd.Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
public void Initialize()
{
ed.WriteMessage("\nPyAcad.NET Loaded Successfully....");
}
public void Terminate()
{
// nothing to do here
//this.Terminate();
}
internal delegate void AddReference(object assembly);
[CommandMethod("pyfile", CommandFlags.Session)]
static public void pythonfile()
{
try
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Python files (*.py)|*.py|All files (*.*)|*.*";
ofd.ShowDialog();
runpyfile(ofd.FileName);
}
catch (System.Exception e)
{
ed.WriteMessage(e.ToString());
}
}
//Lisp example (runpyfile "C:\\print.py")
//returns (T) on success (nil) on error
[LispFunction("runpyfile")]
static public ResultBuffer Lisprunpyfile(ResultBuffer resBuf)
{
TypedValue[] TvArray = resBuf.AsArray();
ResultBuffer retBuf = new ResultBuffer();
if (TvArray[0].TypeCode == (int)LispDataType.Text &&
(string)TvArray[0].Value != string.Empty)
{
if (runpyfile((string)TvArray[0].Value) == true)
{
retBuf.Add(new TypedValue((int)LispDataType.T_atom));
}
else
{
retBuf.Add(new TypedValue((int)LispDataType.Nil));
}
}
return retBuf;
}
//This now returns a bool for our lisp method
static public bool runpyfile(string filename)
{
bool flag = false;
using (PythonEngine engine = new PythonEngine())
{
using (AcadCommandLine myCommandLine = new AcadCommandLine())
{
try
{
// Create a new instance of PythonEngine and set variables.
engine.AddToPath(Environment.CurrentDirectory);
// Send Stdout and Stderr to the AutoCAD command line.
engine.SetStandardOutput(myCommandLine);
engine.SetStandardError(myCommandLine);
engine.Import("clr");
//lets load some AutoCAD assemblies.
AddReference adr = engine.CreateMethod<AddReference>("clr.AddReference(assembly)");
adr(typeof(BlockTableRecord).Assembly);
adr(typeof(Editor).Assembly);
// Run the file selected by the open file dialog box.
//engine.ExecuteFile(ofd.FileName);
CompiledCode cc = engine.CompileFile(filename);
cc.Execute();
flag = true;
}
catch (System.Exception e)
{
ed.WriteMessage(e.ToString());
}
}
}
return flag;
}
}
//
public class AcadCommandLine : Stream
//Modified version of a class coded by Mike Stall.
{
public AcadCommandLine()
{
//constructor
}
#region unsupported Read + Seek members
public override bool CanRead
{
get { return false; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return true; }
}
public override void Flush()
{
//
}
public override long Length
{
get { throw new NotSupportedException("Seek not supported"); } // can't seek
}
public override long Position
{
get
{
throw new NotSupportedException("Seek not supported"); // can't seek
}
set
{
throw new NotSupportedException("Seek not supported"); // can't seek
}
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException("Reed not supported"); // can't read
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException("Seek not supported"); // can't seek
}
public override void SetLength(long value)
{
throw new NotSupportedException("Seek not supported"); // can't seek
}
#endregion
public override void Write(byte[] buffer, int offset, int count)
{
try
{
// Very bad hack: Ignore single newline char. This is because we expect the newline is following
// previous content and we already placed a newline on that.
AcEd.Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
if (count == 1 && buffer[offset] == '\n')
return;
StringBuilder sb = new StringBuilder();
while (count > 0)
{
char ch = (char)buffer[offset];
if (ch == '\n')
{
ed.WriteMessage(sb.ToString() + "\n");
sb.Length = 0; // reset.
}
else if (ch != '\r')
{
sb.Append(ch);
}
offset++;
count--;
}
if (sb.Length > 0)
ed.WriteMessage(sb.ToString() + "\n");
}
catch (System.Exception e)
{
throw e;
}
}
}
}