To All:
I am working on a VB.NET app that will prompt the user to select a folder and then open each dwg in the folder one-at-a-time, zoom extents, create a slide file, and then close the drawing. I have been studying example code done by others in order to use P/Invoke to synchronously execute the "mslide" command from my .NET app. However, I seem to have run into a problem I can't figure out. Below is my VB code as it is now. The app calls a LISP routine which runs the "mslide" command, it is also shown below. The entire project (including the Zoom subroutine) is included in the attached zip file. From the troubleshooting I have done so far, it appears that the LISP routine runs synchronously as expected, but the slide file is not produced and I suspect that the "(command ..)" LISP function is where the error is occurring.
Thanks,
Will
Windows 7
Acad 2010
VB Express 2008
{code}
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports System.IO
Imports System.Windows.Forms
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Interop
Imports System.Runtime.InteropServices
Public Class SOMRClass
'use P/Invoke for acedInvoke
_
Private Shared Function acedInvoke(ByVal args As IntPtr, ByRef result As IntPtr) As Integer
End Function
' Define command 'SlideUpdate'
_
Public Sub SlideUpdate()
Dim FolderBrowserDialog1 As New FolderBrowserDialog 'declare variable for folder browser dialog object
Dim BrowseFolderResult As DialogResult 'declare varialbe for result of dialog
Dim strDirName As String = "" 'declare variable for the path of the folder that will be searched
BrowseFolderResult = FolderBrowserDialog1.ShowDialog() 'show dialog and store result as either OK or cancel
If BrowseFolderResult = DialogResult.OK Then 'check if user clicked OK
strDirName = FolderBrowserDialog1.SelectedPath 'store path of folder selected
End If
'get the value of the "filedia" system variable
Dim FileDiaSysVarOld As Integer = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("filedia")
'set the value of the "filedia" system variable
Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("filedia", 0)
'cycle through each file in the folder that is an AutoCAD drawing
For Each strFileName As String In My.Computer.FileSystem.GetFiles(strDirName, FileIO.SearchOption.SearchAllSubDirectories, "*.dwg")
'declare variable for drawing file object
Dim acDocMgr As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
If (File.Exists(strFileName)) Then 'check if file exists
Dim acDoc As Document = acDocMgr.Open(strFileName, False) 'open the file in the editor
'use the public subroutine Zoom to zoom to extents of drawing
'and scale view outward be a small amount
Zoom(New Point3d(), New Point3d(), New Point3d(), 1.1)
'remove the ".dwg" extension from the file name before passing it to the Mslide command
Dim strFileName2 As String = Replace(strFileName, ".dwg", ".sld", 1, 1, 1)
strFileName2 = Replace(strFileName2, "\", "/", 1, -1, 1)
Dim resBuf As New Autodesk.AutoCAD.DatabaseServices.ResultBuffer()
resBuf.Add(New TypedValue(LispDataType.Text, "c:runmslide"))
resBuf.Add(New TypedValue(LispDataType.Text, strFileName2))
Dim intPtr1 As IntPtr = IntPtr.Zero
Dim intStat As Integer = acedInvoke(resBuf.UnmanagedObject, intPtr1)
resBuf.Dispose()
If intStat <> CInt(Autodesk.AutoCAD.EditorInput.PromptStatus.OK) Then
Throw (New System.Exception("acedInvoke encountered a problem"))
End If
'close and save the current drawing
acDoc.CloseAndSave(strFileName)
Else
'give error message if drawing file does not exist
acDocMgr.MdiActiveDocument.Editor.WriteMessage("File " & strFileName & " does not exist.")
End If
Next 'cycle to the next drawing file
'reset the "filedia" system variable back to its old value
Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("filedia", FileDiaSysVarOld)
End Sub
{code}
Here is the LISP file that is called from the .NET app (note that I write to a log file for troubleshooting purposes) (BTW, make sure you load the LISP routine into the startup suite so that the LISP routine is loaded each time the .NET app opens a new drawing.):
{code}
(defun c:runmslide (slidefilestr /)
(princ "LISP routine started")
(setq errorfile (open "C:/Users/Your Name/My Documents/troubleshoot.log" "a")) ;insert path for log file
(setq date (rtos (getvar 'cdate) 2 8))
(write-line "+++++++++++" errorfile)
(write-line date errorfile)
(write-line "LISP routine started" errorfile)
(command "._mslide" slidefilestr)
(write-line "mslide command complete" errorfile)
(close errorfile)
);end defun
{code}