Hi,
whenever I try to save my curret drawing as I will get this error.
I was looking here what could be the issue but no success yet.
Do you now what could be the problem?
Many thanks.
I used standard method;
Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.Runtime <CommandMethod("SaveActiveDrawing")> _ Public Sub SaveActiveDrawing() Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim strDWGName As String = acDoc.Name Dim obj As Object = Application.GetSystemVariable("DWGTITLED") '' Check to see if the drawing has been named If System.Convert.ToInt16(obj) = 0 Then '' If the drawing is using a default name (Drawing1, Drawing2, etc) '' then provide a new name strDWGName = "c:\MyDrawing.dwg" End If '' Save the active drawing acDoc.Database.SaveAs(strDWGName, True, DwgVersion.Current, _ acDoc.Database.SecurityParameters) End Sub
Solved! Go to Solution.
Ok. I see the root of your problem. The code was designed to be used as extension methods and as the error states, in vb, extension methods must be defined in modules. Please see below:
Imports System.Runtime.CompilerServices Imports System.Reflection Imports Autodesk.AutoCAD Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.ApplicationServices.Application Imports Autodesk.AutoCAD.DatabaseServices Imports System.Threading.Tasks Imports System.IO ''' <summary> ''' Extension Methods ''' </summary> Public Module ModuleExtensions ''' <summary> ''' saves the current drawing ''' </summary> ''' <param name="db">the database / drawing</param> ''' <remarks>We only had to write this because the autocad api is retarded</remarks> <Extension()> Public Sub SaveDamnYou(db As Database) Dim doc As Document = Nothing Try doc = DocumentManager.GetDocument(db) Catch 'db is in batch mode End Try 'If we have a document, attempt to call a quick save If doc IsNot Nothing Then If doc.IsReadOnly Then Throw New ArgumentException("Save failed. Drawing is Read-Only.") Else Try doc.Save() Catch ex As System.Exception doDBSave(db) End Try End If Else 'If no document, attempt to save the database itself doDBSave(db) End If End Sub ''' <summary> ''' Attempts to save the database to itself, or logs an error if it fails ''' </summary> ''' <param name="db"></param> ''' <remarks></remarks> Public Sub doDBSave(db As Database) Try Dim DwgFilePath As String = db.GetRealFilename db.SaveAs(DwgFilePath, True, DwgVersion.Current, db.SecurityParameters) Catch ex As Autodesk.AutoCAD.Runtime.Exception console.writeline(string.format("Acad Error Status: {0}",ex.ErrorStatus)) Throw End Try End Sub ''' <summary> ''' Saves the document via COM ''' </summary> ''' <param name="doc">document to be saved </param> ''' <remarks>Used by the above save routine to allow a lock document to be saved, because the API is SUPER retarded</remarks> <Extension()> Public Sub Save(doc As Document) Dim adoc As Interop.AcadDocument = CType(doc.AcadDocument, Interop.AcadDocument) 'adoc.Save() adoc.SendCommand("_QSAVE ") End Sub ''' <summary> ''' gets the real filename of the database. instead of .sv$ filenames ''' </summary> ''' <param name="db">the database / drawing</param> ''' <returns>returns the real filename</returns> ''' <remarks>http://through-the-interface.typepad.com/through_the_interface/2008/03/getting-the-ful.html</remarks... <Extension()> Public Function GetRealFilename(db As Database) As String Dim doc As Document = Nothing Try doc = DocumentManager.GetDocument(db) Catch 'This error indicates that there is no document object End Try 'is this open in batch mode? If doc Is Nothing Then Return db.Filename Else Return doc.Name End If End Function End Module
Then in your class, you would invoke the save like
<CommandMethod("DOSOMETHING")>
public sub DoSomething()
'...do something here
Autodesk.autocad.applicationservices.application.documentmanager.mdiactivedocument.database.savedamnyou()
end sub
Hi,
finally it worked 🙂 Many thanks. I had to do a minor modification.
How can I save that file to e.g. C:\test.dwg ??
If I change
Dim DwgFilePath As String = db.GetRealFilename
to
Dim DwgFilePath As String = "C:\test.dwg"
it does not work and get the same error eFileAccessErr
Imports System Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.EditorInput Imports System.Runtime.CompilerServices Imports System.Reflection Imports Autodesk.AutoCAD Imports Autodesk.AutoCAD.ApplicationServices.Application Imports System.Threading.Tasks Imports System.IO Imports Autodesk.AutoCAD.Interop <Assembly: CommandClass(GetType(AutoCAD_VB_plug_in1.MyCommands))> Namespace AutoCAD_VB_plug_in1 Public Module ModuleExtensions <Extension()> Public Sub SaveDamnYou(ByVal db As Database) Dim doc As Document = Nothing Try doc = DocumentManager.GetDocument(db) Catch End Try If doc IsNot Nothing Then If doc.IsReadOnly Then Throw New ArgumentException("Save failed. Drawing is Read-Only.") Else Try doc.Save() Catch ex As System.Exception doDBSave(db) End Try End If Else doDBSave(db) End If End Sub Public Sub doDBSave(ByVal db As Database) Try Dim DwgFilePath As String = db.GetRealFilename db.SaveAs(DwgFilePath, True, DwgVersion.Current, db.SecurityParameters) Catch ex As Autodesk.AutoCAD.Runtime.Exception Console.WriteLine(String.Format("Acad Error Status: {0}", ex.ErrorStatus)) Throw End Try End Sub <Extension()> Public Sub Save(ByVal doc As Document) Dim adoc As AcadDocument = CType(doc.AcadDocument, AcadDocument) 'adoc.Save() adoc.SendCommand("_QSAVE ") End Sub <Extension()> Public Function GetRealFilename(ByVal db As Database) As String Dim doc As Document = Nothing Try doc = DocumentManager.GetDocument(db) Catch 'This error indicates that there is no document object End Try 'is this open in batch mode? If doc Is Nothing Then Return db.Filename Else Return doc.Name End If End Function End Module Public Class MyCommands <CommandMethod("DOSOMETHING")> Public Sub DoSomething() '...do something here Autodesk.autocad.applicationservices.application.documentmanager.mdiactivedocument.database.savedamnyou() End Sub End Class End Namespace
Peter,
I must admit I'm a little embarassed... In my haste to show how the ACAD api has issues I didn't address your question... SaveAs as it turns out is much easier... 🙂
Dim newfile As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "drawing1.dwg")
dim db as Database = DocumentManager.MdiActiveDocument.Database
db.SaveAs(newfile, DwgVersion.Current)
This is all that is required to SaveAs. I hope you find a need for savedamnyou though as it's just fun to use... 🙂
Now... let me address why you can't write to c:\test.dwg
If you're running on Windows 7 or Windows 8, then the root of C is protected and UserAccessControl (UAC) is probably affecting you. Hence, my code above finds the users my documents folder and writes there. If you're dead set on writing to c: then right click autocad and choose run as administrator. Then it will let you write to c:
-Jon
Jon,
when I've chosen that option to run it as administrator it worked.
But I had to built the project and load the dll. Can't imagine how to test that code in debug mode, it gives me this error.
Many thanks you helped me to better uderstand what's going on here.
Peter
Can't find what you're looking for? Ask the community or share your knowledge.