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

VB.NET SAVEAS / eFileAccessErr

25 REPLIES 25
SOLVED
Reply
Message 1 of 26
xpeter88
4494 Views, 25 Replies

VB.NET SAVEAS / eFileAccessErr

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

 

25 REPLIES 25
Message 21 of 26
jon-p
in reply to: xpeter88

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

 

Message 22 of 26
xpeter88
in reply to: jon-p

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

 

Message 23 of 26
jon-p
in reply to: xpeter88

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

Message 24 of 26
xpeter88
in reply to: jon-p

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

Message 25 of 26
jon-p
in reply to: xpeter88

Peter,
I'm glad it helped. If you want to debug code that requires admin rights, then you need to start visual studio as an administrator. Right click visual studio and chose Run As Administrator.
Message 26 of 26
xpeter88
in reply to: jon-p

Thanks again Jon 🙂

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