- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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
Solved! Go to Solution.