Author Topic: Overkill Command  (Read 16693 times)

0 Members and 1 Guest are viewing this topic.

TJK44

  • Guest
Overkill Command
« on: April 08, 2013, 11:24:39 AM »
Hi all,

I am trying to use this bit of code to run the overkill command silently in the background. I can't use SendStringToExecute because it does not execute synchronously. After you enter "All" in the autocad command line and select the objects a dialog appears each time the command is run, I would also want to suppress this dialog.
Code - Visual Basic: [Select]
  1.                 Dim rb As New ResultBuffer
  2.                 rb.Add(New TypedValue(5005, "_.OVERKILL"))
  3.                 acedCmd(rb.UnmanagedObject)
  4.  
  5.                 rb = New ResultBuffer
  6.                 rb.Add(New TypedValue(5005, "ALL"))
  7.                 acedCmd(rb.UnmanagedObject)
  8.  
  9.                 rb = New ResultBuffer
  10.                 rb.Add(New TypedValue(5005, vbLf))
  11.                 acedCmd(rb.UnmanagedObject)
  12.  
  13.                 rb = New ResultBuffer
  14.                 rb.Add(New TypedValue(5005, vbLf))
  15.                 acedCmd(rb.UnmanagedObject)
  16.  
  17.                 rb = New ResultBuffer
  18.                 rb.Add(New TypedValue(5005, vbLf))
  19.                 acedCmd(rb.UnmanagedObject)
  20.  
Thanks in advance,

-Ted
« Last Edit: April 08, 2013, 03:35:01 PM by TJK44 »

TheMaster

  • Guest
Re: Overkill Command
« Reply #1 on: April 08, 2013, 02:25:06 PM »
Hi all,

I am trying to use this bit of code to run the overkill command silently in the background. I can't use SendStringToExecute because it does not execute synchronously. After you enter "All" in the autocad command line and select the objects a dialog appears each time the command is run, I would also want to suppress this dialog.

                Dim rb As New ResultBuffer
                rb.Add(New TypedValue(5005, "_.OVERKILL"))
                acedCmd(rb.UnmanagedObject)

                rb = New ResultBuffer
                rb.Add(New TypedValue(5005, "ALL"))
                acedCmd(rb.UnmanagedObject)

                rb = New ResultBuffer
                rb.Add(New TypedValue(5005, vbLf))
                acedCmd(rb.UnmanagedObject)

                rb = New ResultBuffer
                rb.Add(New TypedValue(5005, vbLf))
                acedCmd(rb.UnmanagedObject)

                rb = New ResultBuffer
                rb.Add(New TypedValue(5005, vbLf))
                acedCmd(rb.UnmanagedObject)

Thanks in advance,

-Ted

Hi Ted.  It depends on what AutoCAD release(s) you're trying to use this with.

Overkill was made a built-in command in AutoCAD 2012, but prior to that it was an express tool that could not be automated via acedCmd().


TJK44

  • Guest
Re: Overkill Command
« Reply #2 on: April 08, 2013, 02:26:54 PM »
Hi Tony,

This would be for release 2012 and later. Testing on 2012

TheMaster

  • Guest
Re: Overkill Command
« Reply #3 on: April 08, 2013, 04:21:08 PM »
Hi Tony,

This would be for release 2012 and later. Testing on 2012

You should probably avoid acedCmd() in AutoCAD 2012 or later, since the Editor's RunCommand method does the grunt work for you and also translates all supported types including selection sets, which isn't done by acedCmd(). The Command() wrapper method shown below is one way to use RunCommand() without the overhead of reflection.

Your problem is solved very simply by using the command line version of OVERKILL, whose name starts with a hyphen (e.g., "-OVERKILL").



Code - C#: [Select]
  1. /// Example use of OVERKILL command
  2. /// (AutoCAD 2012 or later only)
  3. /// from managed code.
  4.  
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Reflection;
  10. using Autodesk.AutoCAD.Runtime;
  11. using Autodesk.AutoCAD.EditorInput;
  12. using Autodesk.AutoCAD.ApplicationServices;
  13. using Autodesk.AutoCAD.DatabaseServices;
  14.  
  15. namespace Namespace1
  16. {
  17.    public static class OverkillExample
  18.    {
  19.       [CommandMethod( "MYOVERKILL" )]
  20.       public static void MyOverkill()
  21.       {
  22.          Document doc = Application.DocumentManager.MdiActiveDocument;
  23.          
  24.          // Note the leading "-" on the OVERKILL command, which
  25.          // forces it to use the command line:
  26.          
  27.          doc.Editor.Command( "._-OVERKILL", "_ALL", "", "" );
  28.       }
  29.    }
  30. }
  31.  
  32.  
  33. /// EditorUtils.cs - Non-reflection-based access to the
  34. /// Editor's non-public RunCommand() method.
  35.  
  36. using System;
  37. using System.Collections.Generic;
  38. using System.Linq;
  39. using System.Text;
  40. using System.Linq.Expressions;
  41. using System.Reflection;
  42. using Autodesk.AutoCAD.ApplicationServices;
  43.  
  44. namespace Autodesk.AutoCAD.EditorInput
  45. {
  46.    public static class EditorInputExtensionMethods
  47.    {
  48.       public static PromptStatus Command( this Editor editor, params object[] args )
  49.       {
  50.          if( editor == null )
  51.             throw new ArgumentNullException( "editor" );
  52.          return runCommand( editor, args );
  53.       }
  54.  
  55.       static Func<Editor, object[], PromptStatus> runCommand = GenerateRunCommand();
  56.  
  57.       static Func<Editor, object[], PromptStatus> GenerateRunCommand()
  58.       {
  59.          MethodInfo method = typeof( Editor ).GetMethod( "RunCommand",
  60.             BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public );
  61.          var instance = Expression.Parameter( typeof( Editor ), "instance" );
  62.          var args = Expression.Parameter( typeof( object[] ), "args" );
  63.          return Expression.Lambda<Func<Editor, object[], PromptStatus>>(
  64.             Expression.Call( instance, method, args ), instance, args )
  65.                .Compile();
  66.       }
  67.    }
  68. }
  69.  
  70.  

TJK44

  • Guest
Re: Overkill Command
« Reply #4 on: April 09, 2013, 08:58:51 AM »
Thanks a lot for that example Tony, in the process of trying to get it to work in vb.

Edit:
I'm not that familiar with creating extensions, I tried writing it by hand and using a conversion website. Both ways I am getting an error with the Command Function. I am getting Type Editor and Type PromptStatus are not defined. I created a new class in my project called EditorUtils.vb and added the code below. Any ideas appreciated. Thanks.

Code - Visual Basic: [Select]
  1. Imports System.Collections.Generic
  2. Imports System.Linq
  3. Imports System.Text
  4. Imports System.Linq.Expressions
  5. Imports System.Reflection
  6. Imports Autodesk.AutoCAD.ApplicationServices
  7.  
  8. Namespace AutoDesk.AutoCAD.EditorInput
  9.     Public Class EditorInputExtensionMethods
  10.         Private Sub New()
  11.         End Sub
  12.  
  13.         <System.Runtime.CompilerServices.Extension()> _
  14.         Public Shared Function Command(ByVal editor As Editor, ParamArray args As Object()) As PromptStatus
  15.  
  16.         End Function
  17.     End Class
  18. End Namespace
  19.  
« Last Edit: April 09, 2013, 09:12:26 AM by TJK44 »

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Overkill Command
« Reply #5 on: April 09, 2013, 09:51:31 AM »
Hi,

In VB extension methods have to defined in a module.

Code - vb.net: [Select]
  1. Imports System.Linq.Expressions
  2. Imports System.Reflection
  3. Imports Autodesk.AutoCAD.EditorInput
  4.  
  5. Namespace AcadVb2010
  6.  
  7.     Module EditorInputExtensionMethods
  8.  
  9.         <System.Runtime.CompilerServices.Extension()> _
  10.         Public Function Command(ed As Editor, ParamArray args() As Object)
  11.             If ed Is Nothing Then
  12.                 Throw New ArgumentNullException("editor")
  13.             End If
  14.             Return runCommand(ed, args)
  15.         End Function
  16.  
  17.         Dim runCommand As Func(Of Editor, Object(), PromptStatus) = GenerateRunCommand()
  18.  
  19.         Public Function GenerateRunCommand() As Func(Of Editor, Object(), PromptStatus)
  20.             Dim method As MethodInfo = GetType(Editor).GetMethod( _
  21.                 "RunCommand", BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.[Public])
  22.             Dim instance = Expression.Parameter(GetType(Editor), "instance")
  23.             Dim args = Expression.Parameter(GetType(Object()), "args")
  24.             Return Expression.Lambda(Of Func(Of Editor, Object(), PromptStatus)) _
  25.                 (Expression.[Call](instance, method, args), instance, args).Compile()
  26.         End Function
  27.  
  28.     End Module
  29.  
  30. End Namespace
Speaking English as a French Frog

TJK44

  • Guest
Re: Overkill Command
« Reply #6 on: April 09, 2013, 10:04:43 AM »
Hi and thanks Gile. Are you missing an Imports statement? I am getting 'Func' is ambiguous in namespace System?

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Overkill Command
« Reply #7 on: April 09, 2013, 10:15:44 AM »
Hi and thanks Gile. Are you missing an Imports statement? I am getting 'Func' is ambiguous in namespace System?

No.
Maybe it depends on the Framework targeted (4.0 here).
I'm not very comfortable with VB.
Speaking English as a French Frog

TheMaster

  • Guest
Re: Overkill Command
« Reply #8 on: April 09, 2013, 05:35:25 PM »
Here is what Reflector spits out, and it seems to compile but I haven't actually tried to run it:

Code - Visual Basic: [Select]
  1. Imports Autodesk.AutoCAD.EditorInput
  2. Imports System.Linq.Expressions
  3. Imports System.Reflection
  4.  
  5. <Runtime.CompilerServices.Extension()>
  6. Module Module1
  7.    <Runtime.CompilerServices.Extension()> _
  8.    Public Function Command(ByVal editor As Editor, ByVal ParamArray args As Object()) As PromptStatus
  9.       If (editor Is Nothing) Then
  10.          Throw New ArgumentNullException("editor")
  11.       End If
  12.       Return runCommand.Invoke(editor, args)
  13.    End Function
  14.  
  15.    Private Function GenerateRunCommand() As Func(Of Editor, Object(), PromptStatus)
  16.       Dim instance As ParameterExpression
  17.       Dim args As ParameterExpression
  18.       Dim method As MethodInfo = GetType(Editor).GetMethod("RunCommand", (BindingFlags.NonPublic Or (BindingFlags.Public Or BindingFlags.Instance)))
  19.       Return Expression.Lambda(Of Func(Of Editor, Object(), PromptStatus))(Expression.Call(Expression.Parameter(GetType(Editor), "instance"), method, New Expression() {Expression.Parameter(GetType(Object()), "args")}), New ParameterExpression() {instance, args}).Compile
  20.    End Function
  21.  
  22.  
  23.    ' Fields
  24.   Private runCommand As Func(Of Editor, Object(), PromptStatus) = GenerateRunCommand()
  25.  
  26. End Module
  27.  
  28.  

TJK44

  • Guest
Re: Overkill Command
« Reply #9 on: April 10, 2013, 08:09:59 AM »
For some reason I am still getting the error 'Func' is ambiguous in the namespace 'System'

The target framework is 4.0, attached is a screenshot of what I have for references. Google search doesn't really return anything useful for this certain error either

Edit: I went in to the object explorer and searched for Func. It looks like Func exists in System.Core and mscorlib.

Edit: I changed the target framework from 4.0 to 3.5 and these errors went away. Weird...

« Last Edit: April 10, 2013, 08:40:32 AM by TJK44 »

TJK44

  • Guest
Re: Overkill Command
« Reply #10 on: May 01, 2013, 09:32:04 AM »
Hi,

I am still having the same issue where VS is telling me 'Func' is ambiguous in the namespace 'System'.

I thought maybe it was the project I was working in because it is pretty large in size and didn't want to mess around with too many settings.

I created a new project from scratch using the AutoCAD plug-in wizard and accepted the defaults to the window that pops up.

I created a new class and entered the code as seen below and still get the ambiguous error. Can anyone else verify if they get the same behavior?

Thanks,

-Ted

 
Code - Visual Basic: [Select]
  1. Imports Autodesk.AutoCAD.EditorInput
  2. Imports System.Linq.Expressions
  3. Imports System.Reflection
  4.  
  5. <Runtime.CompilerServices.Extension()>
  6. Module Module1
  7.     <Runtime.CompilerServices.Extension()> _
  8.     Public Function Command(ByVal editor As Editor, ByVal ParamArray args As Object()) As PromptStatus
  9.         If (editor Is Nothing) Then
  10.             Throw New ArgumentNullException("editor")
  11.         End If
  12.         Return runCommand.Invoke(editor, args)
  13.     End Function
  14.  
  15.     Private Function GenerateRunCommand() As System.Func(Of Editor, Object(), PromptStatus)
  16.         Dim instance As ParameterExpression
  17.         Dim args As ParameterExpression
  18.         Dim method As MethodInfo = GetType(Editor).GetMethod("RunCommand", (BindingFlags.NonPublic Or (BindingFlags.Public Or BindingFlags.Instance)))
  19.         Return Expression.Lambda(Of System.Func(Of Editor, Object(), PromptStatus))(Expression.Call(Expression.Parameter(GetType(Editor), "instance"), method, New Expression() {Expression.Parameter(GetType(Object()), "args")}), New ParameterExpression() {instance, args}).Compile
  20.     End Function
  21.  
  22.     ' Fields
  23.    Private runCommand As System.Func(Of Editor, Object(), PromptStatus) = GenerateRunCommand()
  24.  
  25. End Module
  26.  

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Overkill Command
« Reply #11 on: May 01, 2013, 01:35:40 PM »
It will build for me and maybe go to project properties and uncheck it from imported namespaces and see if using a importing statement helps or maybe load up the project.
 
You might have to do a repair on framework.
http://msdn.microsoft.com/en-us/library/8f0k13d2.aspx
 
You could also look at results from Gacutil.exe to help find problems

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Overkill Command
« Reply #12 on: May 01, 2013, 02:13:12 PM »
Hi,

This one works on my computer:
Code - vb.net: [Select]
  1.     Module EditorInputExtensionMethods
  2.  
  3.         <System.Runtime.CompilerServices.Extension> _
  4.         Public Function Command(editor As Editor, ParamArray args As Object()) As PromptStatus
  5.             If editor Is Nothing Then
  6.                 Throw New ArgumentNullException("editor")
  7.             End If
  8.             Return runCommand(editor, args)
  9.         End Function
  10.  
  11.         Dim runCommand As Func(Of Editor, Object(), PromptStatus) = GenerateRunCommand()
  12.  
  13.         Private Function GenerateRunCommand() As Func(Of Editor, Object(), PromptStatus)
  14.             Dim method As MethodInfo = GetType(Editor).GetMethod( _
  15.                 "RunCommand", BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.[Public])
  16.             Dim instance As ParameterExpression = Expression.Parameter(GetType(Editor), "editor")
  17.             Dim args As ParameterExpression = Expression.Parameter(GetType(Object()), "args")
  18.             Return Expression.Lambda(Of Func(Of Editor, Object(), PromptStatus))( _
  19.                 Expression.Call(instance, method, args), instance, args).Compile()
  20.         End Function
  21.  
  22.     End Module
Speaking English as a French Frog

TJK44

  • Guest
Re: Overkill Command
« Reply #13 on: May 01, 2013, 03:37:05 PM »
Quote

It will build for me and maybe go to project properties and uncheck it from imported namespaces and see if using a importing statement helps or maybe load up the project.
 
You might have to do a repair on framework.
http://msdn.microsoft.com/en-us/library/8f0k13d2.aspx
 
You could also look at results from Gacutil.exe to help find problems

Hi Jeff,

Thanks for the suggestions, if you look at the code I posted I did try to fully qualify the name but still getting the ambiguous error.

System.Func should be the fully qualified name right?

Do you think there could be an issue with the .NET 4.0 framework installed on my machine since I created an empty project and it still won't compile?

Edit:
I tried to also create a C# project using the AutoCAD wizard then created a class using Tony's example. Still getting the same error.

Edit:
Looking at the error message close it looks like there is a reference to a file in the AutoDesk folder to System.Core.DLL. What is this, do I need it?
« Last Edit: May 01, 2013, 04:09:42 PM by TJK44 »

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Overkill Command
« Reply #14 on: May 01, 2013, 07:00:03 PM »
The first thing I would do is try to isolate what causes the ambiguity, but I am not familiar with mechanical and can not see why they would distribute assemblies that would clash with BCL.
 
Does the AutoCAD installation folder contain a System.Core.Dll?
Also are you referencing the dll's in SDK or AutoCAD installation folder?
 
To maybe isolate if has to do referencing dll's in AutoCAD folder create a new Windows Console Application and try the code below to see what happens
Code - Visual Basic: [Select]
  1.  
  2.  Module Module1
  3.     Sub Main()
  4.         Dim addOne As Func(Of Integer, Integer) = Function(i) i + 1
  5.         Dim num As Integer
  6.         Console.Write("Enter integer: ")
  7.         While (Not (Integer.TryParse(Console.ReadLine(), num)))
  8.             Console.WriteLine("Please enter an Integer only: ")
  9.         End While
  10.         Console.WriteLine("Adding 1 to {0} is {1}", num, addOne(num))
  11.         Console.Read()
  12.     End Sub
  13. End Module
  14.