You can set it in the registry instead: HKLM\Software\Microsoft\.NETFramework
And set MDA="1" This website http://msdn2.microsoft.com/en-us/library/d21c150d.aspx has a reg file you can use to do it. This will enable MDAs globally for all managed processes on your machine so you'll want to turn it off when you're done. -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Tim Riley Sent: Thursday, August 30, 2007 12:50 PM To: Discussion of IronPython Subject: Re: [IronPython] Hosting: Delegates from Ironpython to C# Dino: I revised the code to what you suggested and still no luck. Is there any way I can set the environment variable other than via the command prompt? My application is hosted inside another application and I can't set the variable from there. Tim On 8/30/07, Dino Viehland <[EMAIL PROTECTED]> wrote: > Setting the env var at runtime won't help, you'll want to set it at a command > prompt and start your app from the command prompt. One other tweak: > > public static void PythonRegister(string CommandName, > CmdDelegate FuncPointer, CommandFlags flags) > { > PythonDelegateWrapper pdw = new PythonDelegateWrapper(FuncPointer)); > RegPyCmd("_pycmds", CommandName, flags, new > CmdDelegate(pdw.Invoke); > GC.KeepAlive(pdw); > } > > Which will ensure it's not a delegate getting collected issue. > > If that doesn't work then we'll need to go into unmanaged debugging territory > w/ windbg/cdb/ntsd :). > > -----Original Message----- > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Tim Riley > Sent: Thursday, August 30, 2007 11:55 AM > To: Discussion of IronPython > Subject: Re: [IronPython] Hosting: Delegates from Ironpython to C# > > Dino: > > I tried using the PythonDelegateWrapper you posted below with the same > results. To make things easier I tried moving all my testing into a > single C# file and have it run the code from C# instead of a compiling > a python file. Below is the code. When I execute "regtest" in AutoCAD > it fatal errors on me. I also added > System.Environment.SetEnvironmentVariable("COMPlus_MDA", "1"); to the > initialize of my code but it doesn't do anything for me. Any other > ideas? > > ********code********* > using System ; > using System.Runtime.InteropServices; > using Autodesk.AutoCAD.Runtime ; > using Autodesk.AutoCAD.EditorInput; > using Autodesk.AutoCAD.ApplicationServices; > using Autodesk.AutoCAD.DatabaseServices; > > using IronPython.Hosting; > > namespace PyAcadDotNet > { > /// <summary> > /// PyAcadCmd Class: > /// Used to register commands on the AutoCAD command stack. > /// </summary> > public class PyAcadCmd > { > public PyAcadCmd() > { > } > public delegate void CmdDelegate(); > internal delegate void AddReference(object assembly); > > /// <summary> > /// RegPyAcadCmd: > /// Registers a delegate (callback) with the AutoCAD command > string > /// on the command stack. > /// </summary> > [DllImport("PyRegCmd.dll", > CallingConvention=CallingConvention.Cdecl,CharSet = > CharSet.Unicode, > EntryPoint = "?RegPyCmd@@[EMAIL PROTECTED]")] > public static extern void RegPyCmd( > string cmd_group, > string cmd_name, > Autodesk.AutoCAD.Runtime.CommandFlags cmd_flags, > [MarshalAs(UnmanagedType.FunctionPtr)] CmdDelegate > cmd_delegate); > > > public static void PythonRegister(string CommandName, > CmdDelegate FuncPointer, CommandFlags flags) > { > RegPyCmd("_pycmds", CommandName, flags, new > CmdDelegate(new PythonDelegateWrapper(FuncPointer).Invoke)); > } > > //testing stuff > public static void testcommand() > { > Editor ed = > Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; > ed.WriteMessage("\ncb1 delegate seems to work!\n"); > } > [CommandMethod("regcmds")] > static public void test() // This method can have any name > { > CmdDelegate cb1 = new CmdDelegate(PyAcadCmd.testcommand); > PythonRegister("testcommand", cb1, CommandFlags.Session); > } > [CommandMethod("regtest", CommandFlags.Session)] > static public void regtest() > { > PythonEngine engine = new PythonEngine(); > engine.Import("clr"); > AddReference adr = > engine.CreateMethod<AddReference>("clr.AddReference(assembly)"); > adr(typeof(BlockTableRecord).Assembly); > adr(typeof(Editor).Assembly); > CompiledCode cc = engine.Compile( > @" > import Autodesk.AutoCAD.Runtime > import clr > clr.AddReference('PyAcadDotNet') > from PyAcadDotNet import PyAcadCmd > def foo(): > print 'hello world' > PyAcadCmd.PythonRegister('pythontester', foo, > Autodesk.AutoCAD.Runtime.CommandFlags.Session)"); > cc.Execute(); > } > } > > class PythonDelegateWrapper > { > private PyAcadCmd.CmdDelegate cmdDelegate; > public PythonDelegateWrapper(PyAcadCmd.CmdDelegate dlg) > { > cmdDelegate = dlg; > } > public void Invoke() > { > cmdDelegate(); > } > } > } > ********code********** > > > > On 8/30/07, Dino Viehland <[EMAIL PROTECTED]> wrote: > > Well at this point we've successfully created the delegate and passed it > > off to you so it's hard to tell what's going wrong here. Couple of > > suggestions on things to try and troubleshoot the issue: > > Instead of handing the delegate you get off to the P/Invoke call > > can you just turn around and invoke the delegate from C# code and > > successfully call back into the Python code? > > If that works can you do something like: > > > > class PythonDelegateWrapper { > > private CmdDelegate cmdDelegate; > > public PythonDelegateWrapper(CmdDelegate dlg) { > > cmdDelegate = dlg; > > } > > > > public void Invoke() { > > cmdDelegate(); > > } > > } > > > > And then pass "new CmdDelegate(new PythonDelegateWrapper(dlg).Invoke)" to > > the P/Invoke function? > > > > The reason why I'm proposing this is maybe there's a strange interaction > > between dynamic methods (which the Python delegate will be) and the > > P/Invoke call - this might help isolate the issue. > > > > And the final thing that might be interesting to try would be to make sure > > you keep the reference to the delegate alive during the lifetime of the > > call. In theory this should be happening for you automatically - but if > > the unmanaged side is going to hold onto this delegate for longer than the > > duration of the call you'll need to do this anyway. Given that you're > > still in the call this shouldn't be an issue but you could set the > > environment variable COMPlus_MDA=1 to enable CLR Managed Debugging > > Assistants to see if you get any warnings about that firing. I don't > > really believe this could be happening but it would be consistent w/ the > > exception you're getting. > > > > Those are my 1st two guesses as to what could be going wrong, hopefully one > > of them will be helpful :). > > > > -----Original Message----- > > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Tim Riley > > Sent: Thursday, August 30, 2007 8:59 AM > > To: Discussion of IronPython > > Subject: Re: [IronPython] Hosting: Delegates from Ironpython to C# > > > > Dino: > > > > I was trying something similar to what you had posted and was getting > > an error. I also just tried the code you gave me with a minor > > correction to fix the CommandFlags part and received the error below. > > If it helps I have also added the C# code use to call the python file > > below the error if that will help at all. > > > > > > *********ERROR*********** > > Command: pyfile > > System.AccessViolationException: Attempted to read or write protected > > memory. > > This is often an indication that other memory is corrupt. > > at PyAcadDotNet.PyAcadCmd.RegPyCmd(String cmd_group, String cmd_name, > > CommandFlags cmd_flags, CmdDelegate cmd_delegate) > > at PyAcadDotNet.PyAcadCmd.PythonRegister(String CommandName, CmdDelegate > > FuncPointer, CommandFlags flags) in C:\Documents and Settings\TJRiley\My > > Documents\pyacaddotnet\registercommand.cs:line 65 > > at PythonRegister##20(Object , Object , Object ) > > at IronPython.Runtime.Calls.CallTarget3.Invoke(Object arg0, Object arg1, > > Object arg2) > > at IronPython.Runtime.Calls.FastCallable3.Call(ICallerContext context, > > Object arg0, Object arg1, Object arg2) > > at IronPython.Runtime.Calls.BuiltinFunction.Call(ICallerContext context, > > Object arg0, Object arg1, Object arg2) > > at IronPython.Runtime.Operations.Ops.CallWithContext(ICallerContext > > context, Object func, Object arg0, Object arg1, Object arg2) > > at C:\Documents and Settings\TJRiley\My > > Documents\pyacaddotnet\Samples\commandmethod_test.py##22(ModuleScope ) > > at IronPython.Hosting.CompiledCodeDelegate.Invoke(ModuleScope > > moduleScope) > > at IronPython.Hosting.CompiledCode.Run(ModuleScope moduleScope) > > at IronPython.Hosting.CompiledCode.Execute(EngineModule engineModule, > > IDictionary`2 locals) > > at IronPython.Hosting.CompiledCode.Execute() > > at PyAcadDotNet.AcadInterface.pythonfile() in C:\Documents and > > Settings\TJRiley\My Documents\pyacaddotnet\PyAcadDotNet.cs:line 98 > > *********ERROR*********** > > > > > > *********CODE************** > > 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 delegate void TestDelegate(); > > > > > > public void Initialize() > > { > > ed.WriteMessage("\nPyAcad.NET Loaded Successfully...."); > > ed.WriteMessage("\ntype 'pyhelp' for commands...."); > > } > > > > public void Terminate() > > { > > this.Terminate(); > > } > > > > internal delegate void AddReference(object assembly); > > > > [CommandMethod("pyfile", CommandFlags.Session)] > > static public void pythonfile() > > { > > 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"); > > PyAcadCmd regcmds = new PyAcadCmd(); > > engine.Globals.Add("regcmds", regcmds); > > //lets load some AutoCAD assemblies. > > AddReference adr = > > engine.CreateMethod<AddReference>("clr.AddReference(assembly)"); > > adr(typeof(BlockTableRecord).Assembly); > > adr(typeof(Editor).Assembly); > > > > // Display an OpenFileDialog and run the script. > > OpenFileDialog ofd = new OpenFileDialog(); > > ofd.Filter = "Python files (*.py)|*.py|All files (*.*)|*.*"; > > ofd.ShowDialog(); > > > > // Run the file selected by the open file dialog box. > > //engine.ExecuteFile(ofd.FileName); > > CompiledCode cc = engine.CompileFile(ofd.FileName); > > cc.Execute(); > > } > > catch (System.Exception e) > > { > > ed.WriteMessage(e.ToString()); > > } > > } > > } > > } > > } > > > > // > > 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; > > } > > } > > } > > } > > *********CODE************** > > On 8/30/07, Dino Viehland <[EMAIL PROTECTED]> wrote: > > > I think you should be able to just pass a function object to > > > PythonRegister and it should be converted into a delegate. For example: > > > > > > import clr > > > clr.AddReference('PyAcadDotNet') > > > from PyAcadDotNet import PyAcadCmd > > > > > > def foo(): > > > print 'hello world' > > > > > > PyAcadCmd.PythonRegister('some command', foo, CommandFlags.Whatever) > > > > > > Does that not work? > > > > > > -----Original Message----- > > > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Tim Riley > > > Sent: Wednesday, August 29, 2007 7:10 PM > > > To: Discussion of IronPython > > > Subject: [IronPython] Hosting: Delegates from Ironpython to C# > > > > > > I'm embedding IronPython in a C# dll that is hosted inside a program > > > called AutoCAD. In order to register commands in AutoCAD from .NET I > > > need to P/Invoke a C function inside a .dll. I can do this fairly easy > > > from C# but I can't figure out the right way to call my C# wrapper > > > from IronPython to have it register the command. I have perused the > > > hosting docs for 1.1 and haven't been able to come up with a solution > > > that works. Here is my C# code. I either want to call the PyRegCmds > > > void or the PythonRegister void. Both of which expect a delegate.for > > > example if I had a python function like: > > > > > > def test1: > > > print "This is a test". > > > > > > I can't figure out how to map test to the delegate required in the code > > > below. > > > Note: I can call this from C# fine. See :static public void test(). > > > > > > Can anyone give me any pointers? It would be greatly appreciated. > > > > > > > > > code: > > > > > > using System ; > > > using System.Runtime.InteropServices; > > > using Autodesk.AutoCAD.Runtime ; > > > using Autodesk.AutoCAD.EditorInput; > > > > > > namespace PyAcadDotNet > > > { > > > /// <summary> > > > /// PyAcadCmd Class: > > > /// Used to register commands on the AutoCAD command stack. > > > /// </summary> > > > public class PyAcadCmd > > > { > > > public PyAcadCmd() > > > { > > > } > > > public delegate void CmdDelegate(); > > > > > > /// <summary> > > > /// RegPyAcadCmd: > > > /// Registers a delegate (callback) with the AutoCAD > > > command string > > > /// on the command stack. > > > /// </summary> > > > [DllImport("PyRegCmd.dll", > > > > > > CallingConvention=CallingConvention.Cdecl,CharSet = CharSet.Unicode, > > > EntryPoint = "?RegPyCmd@@[EMAIL PROTECTED]")] > > > public static extern void RegPyCmd( > > > string cmd_group, > > > string cmd_name, > > > Autodesk.AutoCAD.Runtime.CommandFlags cmd_flags, > > > [MarshalAs(UnmanagedType.FunctionPtr)] > > > PyAcadCmd.CmdDelegate cmd_delegate); > > > > > > > > > public static void PythonRegister(string CommandName, > > > CmdDelegate FuncPointer, CommandFlags flags) > > > { > > > RegPyCmd("_pycmds", CommandName, flags, FuncPointer); > > > } > > > > > > //testing stuff > > > public static void testcommand() > > > { > > > Editor ed = > > > Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; > > > ed.WriteMessage("\ncb1 delegate seems to work!\n"); > > > } > > > [CommandMethod("regcmds")] > > > static public void test() // This method can have any name > > > { > > > CmdDelegate cb1 = new CmdDelegate(PyAcadCmd.testcommand); > > > PythonRegister("testcommand", cb1, CommandFlags.Session); > > > } > > > } > > > > > > > > > } > > > _______________________________________________ > > > Users mailing list > > > [email protected] > > > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > > > _______________________________________________ > > > Users mailing list > > > [email protected] > > > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > > > > > _______________________________________________ > > Users mailing list > > [email protected] > > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > > _______________________________________________ > > Users mailing list > > [email protected] > > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > > > _______________________________________________ > Users mailing list > [email protected] > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > _______________________________________________ > Users mailing list > [email protected] > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > _______________________________________________ Users mailing list [email protected] http://lists.ironpython.com/listinfo.cgi/users-ironpython.com _______________________________________________ Users mailing list [email protected] http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
