Synchronous SENDCOMMAND

Synchronous SENDCOMMAND

Anonymous
Not applicable
4,227 Views
2 Replies
Message 1 of 3

Synchronous SENDCOMMAND

Anonymous
Not applicable

I am trying to write a very simple command processor and in fact the bulk of the code is also used in another .NET program which does function fine and is capable of executing a command (another .NET program) on groups of drawings synchronously without a problem (everything marked as ORIGINAL CODE).

 

Moreover I have been chasing my tail trying a number of configurations and I keep coming back to the same point which is if I have CommandFlags.Session specified in my CommandMethod statement then the application is running in application mode which is necessary so that the SendCommand function will operate synchronously (which it does in my other program).

 

What happens with the code as shown below is the program runs and dutifully brings up each drawing, saves it and closes the file and then when I exit my form it creates three circles in the initial file (Drawing1.DWG) and zooms extents (asynchronous sendcommand).

 

If I disable the CloseAndSave function and instead use Saveas and then CloseandDiscard (which is what my other program uses without problem) the program hangs up AutoCAD after bringing up the initial drawing.

 

This is from the ADNDEV Blog:

If your code is executed in document context, you do not have to lock the document. Therefore, when you execute a command that has been registered via acedDefun(),or when it has been registered via acedRegCmds->addCommand() WITHOUT the ACRX_CMD_SESSION flag (CommandFlags.Session in .NET), YOUR CODE EXECUTES IN DOCUMENT CONTEXT. In this context, AutoCAD LOCKS THE CURRENT DOCUMENT FOR YOU and unlocks it when your function ends. If you have to access other documents in the document context, you have to lock the other documents 'manually'. YOU SHOULD register your command for the application context by using the ACRX_CMD_SESSION command flag (CommandFlags.Session in .NET).

 

My understanding here is if I am using CommandFlags.Session then I am executing in application context (which I was also given to understand is also necessary for SendCommand to execute synchronously) which interestingly is not what IsApplicationContext is indicating.

 

Any help is appreciated (code follows - a cleaner version is attached in PDF).

 

<Autodesk.AutoCAD.Runtime.CommandMethod("ProcessBtn_Click", CommandFlags.Session)> _

    Public Sub ProcessBtn_Click()

    CMDSTR = processCMD()                                                                                                                                           ' Like: CIRCLE 10,10 6 ZOOM E

    Try

        For Each dwg As String In DWGLIST

                '   Dim acDocMgr As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager

                '   Dim doc = DocumentCollectionExtension.Open(acDocMgr, dwg, False)                                                                            

                Dim doc = OpenDWG(dwg, False)                                                                                                                                 ' ORIGINAL CODE

                If doc IsNot Nothing Then

                    Dim indx As Integer

                    FilesList.SelectedIndex = indx : indx = indx + 1

                    Label1.Content = "Pacificorp Batch Command Processor WORKING: OPENING --> " & dwg & " [" & _

                                 indx.ToString & "] Of [ " & DWGLIST.Count.ToString & "]... AppContext is: " & _

                                 Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.IsApplicationContext.ToString

                    '   -----------------------------------------------------------------------------------------

                    Using doclok As Autodesk.AutoCAD.ApplicationServices.DocumentLock = doc.LockDocument

                        If doc.IsReadOnly = False Then

                            Try

                                Dim acapp As AcadApplication = _

                                Marshal.GetActiveObject("AutoCAD.Application.19.1")                                                                                  '   ORIGINAL CODE

                                acapp.ActiveDocument.SendCommand(CMDSTR)                                                                                          '   ORIGINAL CODE

                                '   ------------------------------------------------------------------------------------

                                '   doc.Database.SaveAs(dwg, True, doc.Database.OriginalFileVersion, doc.Database.SecurityParameters)      '   ORIGINAL CODE

                                '   DocumentExtension.CloseAndDiscard(doc)                                                                                                 '   ORIGINAL CODE

                                '   ------------------------------------------------------------------------------------

                                DocumentExtension.CloseAndSave(doc, dwg)  '   Seems to operate in the current thread only

                                '   ------------------------------------------------------------------------------------

                            Catch ex As Autodesk.AutoCAD.Runtime.Exception

                            If doc.IsActive Then DocumentExtension.CloseAndDiscard(doc)

                                MsgBox("Error (Inner): " & ex.Message, MsgBoxStyle.OkOnly, "Batch Processor Error")

                            Finally

                            doc.Dispose()

                            End Try

                        Else

                            Label1.Content = "Batch Command Processor: Doc. Is ReadOnly --> " & dwg

                        End If

                    End Using

           End If

            Next

        Catch ex As Autodesk.AutoCAD.Runtime.Exception

            MsgBox("Error (Outer): " & ex.Message, MsgBoxStyle.OkOnly, "Batch Processor Error")

        End Try

End Sub

 

Public Function SelectDoc(ByVal filename As String, _

     Optional ByVal ForWrite As Boolean = False) As Document

   Dim docs As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager

  Try

      For Each doc As Document In docs

          If doc.Name.ToUpper = fullname.ToUpper Then

              If doc.Name = Autodesk.AutoCAD.ApplicationServices.

                           Application.DocumentManager.MdiActiveDocument.Name Then

                If doc.IsReadOnly = Not ForWrite Or doc.IsReadOnly = False Then

                     Return doc

                 Else

                    Return Nothing

                 End If

             Else

                 If doc.IsReadOnly <> ForWrite Or ForWrite = False Then

                     Autodesk.AutoCAD.ApplicationServices.

                     Application.DocumentManager.MdiActiveDocument = doc

                     Return doc

                Else

                     Return Nothing

                 End If

              End If

         End If

       Next

Catch ex As SystemException

         MsgBox("Error in OpenDWG [" & ex.Message & "] ", MsgBoxStyle.OkOnly,  "Command Process")

   End Try

   Return Nothing

End Function

 

 

Public Function OpenDWG(ByVal fullname As String, ByVal ForReadOnly As Boolean) As Document

   Try

       Dim docs As DocumentCollection = _      

                               Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager

       Try

          Dim doc As Document = SelectDoc(fullname, Not ForReadOnly)

          If doc IsNot Nothing Then

              Return doc

         Else

              doc = DocumentCollectionExtension.Open(docCol:=docs, fileName:=fullname, _

                                                     forReadOnly:=False)       

              If ForReadOnly = False And doc.IsReadOnly = True Then

                 doc.DowngradeDocOpen(True)

                  Return Nothing

             Else

                 Return doc

             End If

          End If

Catch ex As SystemException

         MsgBox("Error in OpenDWG [" & ex.Message & "] ", MsgBoxStyle.OkOnly,  "Command Process")

           Return Nothing

       End Try

    Catch ex As SystemException

       MsgBox("Error in OpenDWG [" & ex.Message & "] ", MsgBoxStyle.OkOnly,  "Command Process")             Return Nothing

   End Try

End Function

 

 

 

 

0 Likes
Accepted solutions (1)
4,228 Views
2 Replies
Replies (2)
Message 2 of 3

hgasty1001
Advisor
Advisor

Hi,

 

You may find interesting this post from Gilles Chanteau in The Swamp: Editor.Command vs Editor.CommandAsync

 

Gaston Nunez

0 Likes
Message 3 of 3

Anonymous
Not applicable
Accepted solution

Gaston --

 

Yes very interesting indeed and good to know I will be trying Editor.command in place of Sendcommand for sure.

 

However I discovered the problem I was experiencing had nothing to do with the Sendcommand function or application context for that matter I was using a modal form when I should have been using a modeless one, when I made the change everything began to work again.  

 

I was pointed in that direction from another post in the forum: Please verify: DocumentCollection.Open(dwgfileName) does not work when a modal dialog box is loaded.

 

Thank you very much.

 

Jim --

0 Likes