.NET

.NET

Reply
Valued Contributor
chockalingam
Posts: 86
Registered: ‎03-06-2012
Message 1 of 13 (1,384 Views)

Send Command Executes after exiting command method

1384 Views, 12 Replies
04-23-2013 06:48 PM

Hi,

  I used send command for Export Layout

  But the line only executes after exiting command method.

 Can anyone help in this case.

 

thanks in advance.

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 2 of 13 (1,375 Views)

Re: Send Command Executes after exiting command method

04-23-2013 07:37 PM in reply to: chockalingam

SendCommand is asynchronous, and works that way.

 

If you are on a version of AutoCAD that uses .NET 3.5 or later, you can use this wrapper for RunCommand

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Reflection;
using Autodesk.AutoCAD.ApplicationServices;
 
namespace Autodesk.AutoCAD.EditorInput
{
   public static class EditorInputExtensionMethods
   {
      public static PromptStatus Command( this Editor editor, params object[] args )
      {
         if( editor == null )
            throw new ArgumentNullException( "editor" );
         return runCommand( editor, args );
      }
 
      static Func<Editor, object[], PromptStatus> runCommand = GenerateRunCommand();
 
      static Func<Editor, object[], PromptStatus> GenerateRunCommand()
      {
         MethodInfo method = typeof( Editor ).GetMethod( "RunCommand", 
            BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public );
         var instance = Expression.Parameter( typeof( Editor ), "instance" );
         var args = Expression.Parameter( typeof( object[] ), "args" );
         return Expression.Lambda<Func<Editor, object[], PromptStatus>>(
            Expression.Call( instance, method, args ), instance, args )
               .Compile();
      }
   }
}
 
 

 

With the above code, you can use this:

 

   Document doc = Application.DocumentManager.MdiActiveDocument;

   Editor editor = doc.Editor;

   editor.Command( "._EXPORTLAYOUT", "filename-goes-here" );

 

 

Valued Contributor
chockalingam
Posts: 86
Registered: ‎03-06-2012
Message 3 of 13 (1,366 Views)

Re: Send Command Executes after exiting command method

04-23-2013 08:52 PM in reply to: chockalingam

Included the wrapper. Even now it is not working.

 

Following is the code i'm using,

 

 

Document doc = Application.DocumentManager.MdiActiveDocument;
Database AcDb = doc.Database;
using (Transaction tr = AcDb.TransactionManager.StartTransaction())
{
LayoutManager AcLtMgr = LayoutManager.Current;
DBDictionary layoutDic = tr.GetObject(AcDb.LayoutDictionaryId, OpenMode.ForRead, false) as DBDictionary;
ObjectId layoutId;
Layout layout;
foreach (DBDictionaryEntry entry in layoutDic)
{

layoutId = entry.Value;
layout = tr.GetObject(layoutId, OpenMode.ForRead) as Layout;
if (!layout.LayoutName.Equals("Model"))
{
LayoutManager.Current.CurrentLayout = layout.LayoutName;

string filename = Path.Combine(Path.GetTempPath(), layout.LayoutName + ".dwg");
Editor editor = doc.Editor;
editor.Command("._EXPORTLAYOUT", filename);
}
}
tr.Commit();
}

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 4 of 13 (1,358 Views)

Re: Send Command Executes after exiting command method

04-23-2013 09:29 PM in reply to: DiningPhilosopher

Sorry, I'm not sure what "not working" means.

 

What exactly happens?

 

 

 

Valued Contributor
chockalingam
Posts: 86
Registered: ‎03-06-2012
Message 5 of 13 (1,350 Views)

Re: Send Command Executes after exiting command method

04-23-2013 09:35 PM in reply to: DiningPhilosopher

HI,

  Sorry, for not explaining clearly.

  I am trying to export the layout to new drawing.

  So, I used ExpotLayout.

  But i'm not getting the output file.

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 6 of 13 (1,301 Views)

Re: Send Command Executes after exiting command method

04-24-2013 08:28 AM in reply to: chockalingam

The Command() method shouldn't be used inside an active Transaction, so first, commit the transaction before you use the Command() method. You can also skip all of that code that gets the current layout name by just reading the CTAB system variable, and do away with the use of the transaction entirely.

When using the Command() method, you are basically using a managed wrapper for the LISP (command) function, so the CMDECHO system variable should be set to 0 under normal use, but should be set to 1 when you're debugging so that you can see the prompts issued by the commands. Try running the code with CMDECHO set to 1 and see what the command is doing.

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 7 of 13 (1,270 Views)

Re: Send Command Executes after exiting command method

04-24-2013 03:35 PM in reply to: chockalingam

Just to be sure there wasn't a problem with my wrapper for RunCommand, I added your use case to the set of tests and examples I have for it.

 

Here's a working example:

 

/// ExportLayouts.cs  (c) 2013  Tony Tanzillo
/// 
/// AutoCAD.NET API sample that automates
/// the EXPORTLAYOUT command to export all
/// layouts in the current document.
/// 
/// This example requires EditorExtensions.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Linq.Expressions;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;

namespace ExportLayoutsExample
{
   public static class ExportLayoutsCommands
   {
      /// 
      /// Automates the EXPORTLAYOUT command to export 
      /// all paper space layouts to .DWG files.
      /// 
      /// In this example, we export each layout to
      /// a drawing file in the same location as the
      /// current drawing, wherein each file has the
      /// name "_.dwg".
      /// 
      /// This is not a functionally-complete example:
      /// 
      /// No checking is done to see if any of the 
      /// files already exist, and existing files 
      /// are overwritten without warning or error.
      /// 
      /// No checking is done to detect if an existing
      /// file exists and is in-use by another user, or 
      /// cannot be overwritten for any other reason.
      /// 
      /// No checking is done to ensure that the user
      /// has sufficient rights to write files in the
      /// target location.
      /// 
      /// You can and should deal with any or all of
      /// the above as per your own requirements.
      /// 
      /// 

      [CommandMethod( "EXPORTLAYOUTS" )]
      public static void ExportLayoutsCommand()
      {
         var doc = Application.DocumentManager.MdiActiveDocument;
         var db = doc.Database;
         var editor = doc.Editor;
         try
         {
            if( (short) Application.GetSystemVariable( "DWGTITLED" ) == 0 )
            {
               editor.WriteMessage(
                  "\nCommand cannot be used on an unnamed drawing"
               );
               return;
            }
            string format =
               Path.Combine(
                  Path.GetDirectoryName( doc.Name ),
                  Path.GetFileNameWithoutExtension( doc.Name ) )
               + "_{0}.dwg";

            string[] layoutNames = null;

            using( Transaction tr = doc.TransactionManager.StartTransaction() )
            {
               // Get the localized name of the model tab:
               BlockTableRecord btr = (BlockTableRecord)
                  SymbolUtilityServices.GetBlockModelSpaceId( db )
                     .GetObject( OpenMode.ForRead );
               Layout layout = (Layout)
                  btr.LayoutId.GetObject( OpenMode.ForRead );
               string model = layout.LayoutName;
               // Open the Layout dictionary:
               IDictionary layouts = (IDictionary)
                  db.LayoutDictionaryId.GetObject( OpenMode.ForRead );
               // Get the names of all paper space layouts into a list:
               layoutNames = layouts.Keys.Cast()
                  .Where( name => name != model ).ToArray();

               tr.Commit();
            }

            int cmdecho = 0;
#if DEBUG
            cmdecho = 1;
#endif
            using( new ManagedSystemVariable( "CMDECHO", cmdecho ) )
            using( new ManagedSystemVariable( "CMDDIA", 0 ) )
            using( new ManagedSystemVariable( "FILEDIA", 0 ) )
            using( new ManagedSystemVariable( "CTAB" ) )
            {
               foreach( string name in layoutNames )
               {
                  string filename = string.Format( format, name );
                  editor.WriteMessage( "\nExporting {1}\n", name, filename );
                  Application.SetSystemVariable( "CTAB", name );
                  editor.Command( "._EXPORTLAYOUT", filename );
               }
            }
         }
         catch( System.Exception ex )
         {
#if DEBUG
            editor.WriteMessage( ex.ToString() );
#else
            throw ex;
#endif
         }
      }
   }

   public static class EditorInputExtensionMethods
   {
      public static PromptStatus Command( this Editor editor, params object[] args )
      {
         if( editor == null )
            throw new ArgumentNullException( "editor" );
         return runCommand( editor, args );
      }

      static Func<Editor, object[], PromptStatus> runCommand = GenerateRunCommand();

      static Func<Editor, object[], PromptStatus> GenerateRunCommand()
      {
         MethodInfo method = typeof( Editor ).GetMethod( "RunCommand",
            BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public );
         var instance = Expression.Parameter( typeof( Editor ), "instance" );
         var args = Expression.Parameter( typeof( object[] ), "args" );
         return Expression.Lambda<Func<Editor, object[], PromptStatus>>(
            Expression.Call( instance, method, args ), instance, args )
               .Compile();
      }
   }


   /// 
   /// Automates saving/changing/restoring system variables
   /// 
   
   public class ManagedSystemVariable : IDisposable
   {
      string name = null;
      object oldval = null;

      public ManagedSystemVariable( string name, object value )
         : this( name )
      {
         Application.SetSystemVariable( name, value );
      }

      public ManagedSystemVariable( string name )
      {
         this.name = name;
         this.oldval = Application.GetSystemVariable( name );
      }

      public void Dispose()
      {
         if( oldval != null )
         {
            object temp = oldval;
            oldval = null;
            Application.SetSystemVariable( name, temp );
         }
      }
   }

}

 

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 8 of 13 (1,248 Views)

Re: Send Command Executes after exiting command method

04-25-2013 04:12 AM in reply to: DiningPhilosopher
Press F1 and see about EXPORTLAYOUT command,
seems to me this will not working from comand line
Or I'm missed something again?
_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 9 of 13 (1,238 Views)

Re: Send Command Executes after exiting command method

04-25-2013 09:08 AM in reply to: Hallex

Hallex wrote:
Press F1 and see about EXPORTLAYOUT command,
seems to me this will not working from comand line
Or I'm missed something again?

In recent releases it is implemented in managed code, and can be called via LISP's (command) function.

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 10 of 13 (1,235 Views)

Re: Send Command Executes after exiting command method

04-25-2013 09:21 AM in reply to: DiningPhilosopher

The above posted code will not compile as-is because the Autodesk discussion group server has mangled the code  (removing some angle braces).

 

A copy that actually compiles can be found here:

 

    http://www.theswamp.org/index.php?topic=44472.0

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.