.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Help with P/Invoke

1 REPLY 1
Reply
Message 1 of 2
SOMAR_engineering
494 Views, 1 Reply

Help with P/Invoke

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}
1 REPLY 1
Message 2 of 2

Well, I got my application working but not in the way I was expecting. It turns out that using P/Invoke was not necessary. I was under the misconception that SendCommand would not work for what I wanted to do. The following thread was very helpful in correcting my misunderstanding:

http://discussion.autodesk.com/forums/thread.jspa?messageID=6215733�

The following code allows the "mslide" command to run synchronously:

{code}
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports AcadAp = Autodesk.AutoCAD.ApplicationServices.Application
Imports Autodesk.AutoCAD.DatabaseServices
Imports System.IO
Imports System.Windows.Forms
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
Imports System.Runtime.InteropServices


Public Class SOMRClass

Private AcadObj As AcadApplication = AcadAp.AcadApplication
Private Function ThisDrawing() As AcadDocument
Return AcadObj.ActiveDocument
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 = AcadAp.GetSystemVariable("filedia")
'set the value of the "filedia" system variable
AcadAp.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 = AcadAp.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)

ThisDrawing.SendCommand("_mslide" & vbCr & strFileName2 & vbCr)

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
AcadAp.SetSystemVariable("filedia", FileDiaSysVarOld)
End Sub
End Class
{code}

I still do not know why the LISP routine in my first post was not working and if anyone has figured it out I would still like to know. But for the purposes of getting my application working the problem is solved.

Thanks,
Will

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost