• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Distinguished Contributor
    VB_Autocad_guy
    Posts: 136
    Registered: ‎07-24-2009
    Accepted Solution

    Database.Save "eFileSharingViolation"

    498 Views, 11 Replies
    03-26-2012 12:24 PM

    Need some help here: 

    Any clue why I'm getting this error? 

     

      Sub LoopThroughFolderOfDwgsAndUpdateHyperlinks()
    
    
            Dim myCounter As Integer = 0
    
            ' First create a FolderBrowserDialog object
            Dim FolderBrowserDialog1 As New FolderBrowserDialog
    
            ' Then use the following code to create the Dialog window
            ' Change the .SelectedPath property to the default location
            With FolderBrowserDialog1
                ' Desktop is the root folder in the dialog.
                .RootFolder = Environment.SpecialFolder.Desktop
                ' Select the C:\Windows directory on entry.
                .SelectedPath = "Q:\"
              
    
                If .ShowDialog = DialogResult.OK Then
                    ' Display the selected folder if the user clicked on the OK button.
    
                    Dim files() As String = Directory.GetFiles(.SelectedPath, "*.dwg", SearchOption.TopDirectoryOnly)
                    For Each file In files
    
                        'do code to files
    
                        If (System.IO.File.Exists(file.ToString)) Then
    
                            'Try
                                'Create Database Object to Store Drawing Info into
                                Dim myDB As New DatabaseServices.Database
    
                                'Read Drawing File
                                myDB.ReadDwgFile(file, FileOpenMode.OpenForReadAndWriteNoShare, False, "")
    
                                'TODO: Error Catching for files already opened...
    
                                'UPDATE THE HYPERLINKS IF FILE OPENS
                                UpdateHyperlinksInDocument(myDB)
    
                                'Processed File Count
                                myCounter = myCounter + 1
    
    '!!!!!!!!!!ERRROR ON THIS LINE "myDB.SaveAs"
                                'Save Drawing
                            myDB.SaveAs(file, False, DwgVersion.Current, myDB.SecurityParameters)
    
                                'File Processed Successfully
                                gsFileSuccessList.Add(file)
    
                                'Clean-up Memory Object
                                myDB.Dispose()
    
                            'Catch ex As Exception
                            '    Debug.Print(ex.Message & "On file:" & file)
                            '    gsFileErrorList.Add(file)
    
                            'End Try
                     
    
    
                        Else
                            Debug.Print("Can't Find and Open File : " & file)
                            gsFileErrorList.Add(file)
    
                        End If
    
                    Next
                End If
    
            End With
    
    
            MsgBox("Processed: [" & myCounter & "] AutoCad files" & vbCrLf & _
                  "Succesfully Added: [" & gintHyperlinkCounter & "] hyperlinks")
    
            If gsFileSuccessList.Count > 0 Then
    
                Dim sFileList As String = String.Empty
                For i = 0 To gsFileSuccessList.Count - 1
                    sFileList = sFileList + (gsFileSuccessList.Item(i) & vbCrLf)
                Next
    
                MsgBox("Successfully processed the following files: " & vbCrLf & _
                        sFileList)
            End If
    
    
            If gsFileErrorList.Count > 0 Then
    
                Dim sFileList As String = String.Empty
                For i = 0 To gsFileErrorList.Count - 1
                    sFileList = sFileList + (gsFileErrorList.Item(i) & vbCrLf)
                Next
    
                MsgBox("Couldn't Process the following files: " & vbCrLf & _
                        sFileList)
            End If
    
    
    
    
        End Sub

     

    Please use plain text.
    *Expert Elite*
    Hallex
    Posts: 1,334
    Registered: ‎10-08-2008

    Re: Database.Save "eFileSharingViolation"

    03-26-2012 11:31 PM in reply to: VB_Autocad_guy

                     Try to use this line instead :

                           'Read Drawing File              

               myDB.ReadDwgFile(file, FileShare.ReadWrite, False, "")

     

                    And also this line may different syntax relative to your Acad version:

     

                            'Save Drawing              

               myDB.SaveAs(file, False, DwgVersion.Current, myDB.SecurityParameters)

     

                    Try instead:

     

                           myDB.SaveAs(file, False, DwgVersion.Current)

     

    ~'J'~

    _____________________________________
    C6309D9E0751D165D0934D0621DFF27919
    Please use plain text.
    *Expert Elite*
    Hallex
    Posts: 1,334
    Registered: ‎10-08-2008

    Re: Database.Save "eFileSharingViolation"

    03-27-2012 04:42 AM in reply to: VB_Autocad_guy

     

    If this would be interesting for you:

    Here is your working code , I've just changed inner Sub for test

    (currently I changed one attribute for all title blocks in modelspace)

    It's working good on A2010 both Debug and Release mode

            Public Shared Sub LoopThroughFolderOfDwgsAndUpdateHyperlinks()
    
                Dim myCounter As Integer = 0
    
                ' First create a FolderBrowserDialog object
                Dim FolderBrowserDialog1 As New FolderBrowserDialog
    
                ' Then use the following code to create the Dialog window
                ' Change the .SelectedPath property to the default location
                With FolderBrowserDialog1
                    ' Desktop is the root folder in the dialog.
                    .RootFolder = Environment.SpecialFolder.Desktop
                    ' Select the C:\Windows directory on entry.
                    .SelectedPath = "C:\MyDirectory\MyFolder"
    
    
                    If .ShowDialog = DialogResult.OK Then
                        ' Display the selected folder if the user clicked on the OK button.
    
                        Dim files() As String = Directory.GetFiles(.SelectedPath, "*.dwg", SearchOption.TopDirectoryOnly)
                        Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
                        Using docloc As DocumentLock = doc.LockDocument
                            For Each file In files
                                'do code to files
                                If (System.IO.File.Exists(file)) Then
                                    Try
                                        'Create Database Object to Store Drawing Info into
                                        Using myDB As Database = New Database
    
                                            'Read Drawing File
                                            myDB.ReadDwgFile(file, FileShare.ReadWrite, False, "")
    
                                            'TODO: Error Catching for files already opened...
    
                                            'UPDATE THE HYPERLINKS IF FILE OPENS
                                            UpdateHyperlinksInDocument(myDB)'
                                            'ChangeTitleBlock(myDB)'<-- used for test
    
                                            'Processed File Count
                                            myCounter = myCounter + 1
    
                                            '!!!!!!!!!!ERRROR ON THIS LINE "myDB.SaveAs"
                                            'Save Drawing
                                            myDB.SaveAs(file, False, DwgVersion.Current, myDB.SecurityParameters)
    
                                            'File Processed Successfully
                                            gsFileSuccessList.Add(file)
    
                                            'Clean-up Memory Object
                                            'myDB.Dispose()
                                        End Using
                                    Catch ex As Exception
                                        MsgBox(ex.Message & "On file:" & file & vbLf & "Trace: " & vbLf & ex.StackTrace)
                                        gsFileErrorList.Add(file)
    
                                    End Try
                                Else
    
                                    MsgBox("File does not existse:" & file)
                                End If
                            Next
                        End Using
                    End If
    
                End With
    
    
                'MsgBox("Processed: [" & myCounter & "] AutoCad files" & vbCrLf & _
                '      "Succesfully Added: [" & gintHyperlinkCounter & "] hyperlinks")
    
                If gsFileSuccessList.Count > 0 Then
    
                    Dim sFileList As String = String.Empty
                    For i = 0 To gsFileSuccessList.Count - 1
                        sFileList = sFileList + (gsFileSuccessList.Item(i) & vbCrLf)
                    Next
    
                    MsgBox("Successfully processed the following files: " & vbCrLf & _
                            sFileList)
                End If
    
    
                If gsFileErrorList.Count > 0 Then
    
                    Dim sFileList As String = String.Empty
                    For i = 0 To gsFileErrorList.Count - 1
                        sFileList = sFileList + (gsFileErrorList.Item(i) & vbCrLf)
                    Next
    
                    MsgBox("Couldn't Process the following files: " & vbCrLf & _
                            sFileList)
                End If
    
            End Sub

     

     

    ~'J'~

    _____________________________________
    C6309D9E0751D165D0934D0621DFF27919
    Please use plain text.
    Distinguished Contributor
    VB_Autocad_guy
    Posts: 136
    Registered: ‎07-24-2009

    Re: Database.Save "eFileSharingViolation"

    03-27-2012 08:35 AM in reply to: Hallex

    Hallex thanks for taking the time to test out my code!

    Still no luck on my end. 

     

    I get A first chance exception of type 'System.NullReferenceException' occurred in ClassAutocad2011.dll

     

    and then now I get,

     

    FATAL ERROR: Unhandled Access Violation Reading 0x0000 Exception at 138e9e2bh

     

    Using Autocad 2011, Visual Studio 2008, Win XP 32-bit

     

    Hmm.... I'll keep trying.

    Please use plain text.
    *Expert Elite*
    Hallex
    Posts: 1,334
    Registered: ‎10-08-2008

    Re: Database.Save "eFileSharingViolation"

    03-27-2012 09:18 AM in reply to: VB_Autocad_guy

    Seems to me the problem is on your sub routines

    Try in Debug mode set Option Strict to On, then hit

    Build Solution I'm sure you will be see some errors

    in the Errors window

    After you will fix them all set Option Strict to Off back

    and try again

    I've tested code on Win 7 VS 2010

    Sorry  I have not have any other ideas

     

    ~'J'~

    _____________________________________
    C6309D9E0751D165D0934D0621DFF27919
    Please use plain text.
    Distinguished Contributor
    VB_Autocad_guy
    Posts: 136
    Registered: ‎07-24-2009

    Re: Database.Save "eFileSharingViolation"

    03-27-2012 10:54 AM in reply to: Hallex

    Got it working! YEAH!

     

      <CommandMethod("runbatch")> _
        Sub ProcessFolderPath()
            
    
            '<<FOLDER DIALOGUE------------------------------------------------------------------
            ' First create a FolderBrowserDialog object
            Dim FolderBrowserDialog1 As New FolderBrowserDialog
            Dim myFolderPath As String = ""
    
            ' Then use the following code to create the Dialog window
            ' Change the .SelectedPath property to the default location
            With FolderBrowserDialog1
    
                ' Desktop is the root folder in the dialog.
                .RootFolder = Environment.SpecialFolder.Desktop
    
                ' Select the C:\Windows directory on entry.
                .SelectedPath = "Q:\"
    
                ' Prompt the user with a custom message.
                .Description = "Select the directory of P&ID Drawings"
    
                If .ShowDialog = DialogResult.OK Then
                    myFolderPath = .SelectedPath
    
                    LoopThroughFilesInDirectory(myFolderPath, SearchOption.TopDirectoryOnly)
                Else
                    Exit Sub
    
                End If
    
    
            End With
    
        End Sub
    
        Sub LoopThroughFilesInDirectory(ByVal myFolderPath As String, ByVal mySearchOption As SearchOption)
    
    
            '<<Loop Through Files------------------------------------------------------------------------------------
            Dim files() As String = Directory.GetFiles(myFolderPath, "*.dwg", mySearchOption)
    
            For Each File In files
                'Debug.Print("Processing File: " & File & Environment.NewLine)
                ProcessFile(File, eBlockScripts.UpdateHyperlinksInDrawing)
    
            Next
    
        End Sub
    
        <CommandMethod("eatthiscat")> _
    Sub eatthiscat()
            ProcessFile("C:\cat.dwg", eBlockScripts.UpdateHyperlinksInDrawing)
        End Sub
    
        Sub ProcessFile(ByVal myFile As String, ByVal ProcessAction As eBlockScripts)
    
            'Detect if File Exists
            If System.IO.File.Exists(myFile) = True Then
                'ED_VBNET.WriteMessage(myFile & Environment.NewLine)
            Else
                ED_VBNET.WriteMessage("Can't find file: " & myFile & Environment.NewLine)
                Exit Sub
            End If
    
            '<< Modify Files ----------------------------------------------------------------------------------------
            'Create Database Object to Store Drawing Info into
            Using myDB As New DatabaseServices.Database(False, True)
    
                'Read Drawing File
                myDB.ReadDwgFile(myFile, FileShare.ReadWrite, False, "")
    
                'Action to Accomplish to File
                UpdateLivelinkHyperlinksInDocument(myDB)
    
                'Save Changes to File
                myDB.SaveAs(myFile, DwgVersion.Current)
    
    
            End Using
    
        End Sub
    
        ''' <summary>
        ''' This Is a List of Common Script Actions to Apply to a Cad Drawing
        ''' </summary>
        ''' <remarks></remarks>
        Public Enum eBlockScripts
            NoAction
            UpdateHyperlinksInDrawing
            InsertDrawingStamp
    
        End Enum

     

    Please use plain text.
    *Expert Elite*
    Hallex
    Posts: 1,334
    Registered: ‎10-08-2008

    Re: Database.Save "eFileSharingViolation"

    03-27-2012 01:18 PM in reply to: VB_Autocad_guy

    Good to hear it

    Cheers :smileyhappy:

     

    ~'J'~

    _____________________________________
    C6309D9E0751D165D0934D0621DFF27919
    Please use plain text.
    *Expert Elite*
    Posts: 681
    Registered: ‎04-27-2009

    Re: Database.Save "eFileSharingViolation"

    03-30-2012 12:47 PM in reply to: VB_Autocad_guy

    Sorry to post against a question that seemed being solved for a quite while.

     

    However, I think all the answers do not really solve the actual issue raised by the OP, although the OP made the code change as other suggested and seemed satisfied.

     

    The real issue is the enum type "Autodesk.AutoCAD.DatabaseServices.FileOpenMode.OpenForReadAndWriteNoShare" used in the ReadDwgFile() method causes AutoCAD crash. All the suggestions in the replied post uses the overloaded ReadDwgFile() method with System.IO.FileShare.ReadWrite for the second argument.

     

    AFAIK, the overloaded ReadDwgFile() method with Autodesk.AutoCAD.DatabaseServices.FileOenMode argument was introduced into Acad's .NET API in version 18.x (2007/8/9, but I am not sure which one. I only have Acad2009 as oldest Acad available). All my code where ReadDwgFile() is needed uses System.IO.FileShare, because the code was written against Acad2006 and I never thought I need to update the code.

     

    After seeing the OP, being curoius, I wrote following simple code to try to find why using FileOpenMode causes Acad crash:

     

    public class Commands
    {
        [CommandMethod("FileOpenMode")]
        public static void OpenFileModeTest()
        {
            //A simple drawing file
            string dwgFile = @"C:\Work\Acad\SomeDrawing.DWG";
    
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
    
            using (Database db = new Database(false, false))
            {
                try
                {
                    //read dwg file
                    db.ReadDwgFile(dwgFile, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
    
                    //Does nothing but immediately save the database
                    db.SaveAs(dwgFile, DwgVersion.Current);
                }
                catch (System.Exception ex)
                {
                    ed.WriteMessage("\nError: {0}", ex.Message);
                }
            }
        }
    }

     

     

     As we can see, the code is very simple: just call ReadDwgFile() and then Database.SaveAs(). Then I tried it with differnt AutoCAD version:

     

    Acad2009, 32bit - the code runs OK. That is, the Database is successfuly saved back.

    Acad2011, 32bit - The Database.SaveAs() throw "eFileSharingViolation" error.

    Acad2012, 64bit - the same "eFilesharingViolation" error, in 2 different computers.

     

    Of course, when tried with Sytem.ID.FileShare.ReadWrite parameter in ReadDwgFile(), Database.SaveAs() runs OK with all Acad versions I tested.

     

    When doing the test, the drawing file is from my local HD, absolutely no other Acad instance is accessing it for sure.

     

    To me, it is quite obvious: Acad version 19.x (2010/2011/2012, although I do not have Acad2010 at hand, but I'd be willing to bet on it) breaks the ReadDwgFile() with FileOpenMode.OpenForReadWritenoShar argument.

     

    BTW, I did not test with other FileOpenMode value, because it seems the OpenForReadWriteNoShare value should be the direct reason of the trouble.

     

    Can anyone verify this with your Acad version? Since Acad2013 has been released,can someone verify this with Acad2013 (bother 32bit/64bit)?

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,168
    Registered: ‎04-09-2008

    Re: Database.Save "eFileSharingViolation"

    03-30-2012 02:36 PM in reply to: norman.yuan

    Try:

    using (Database db = new Database(false, true))

    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.
    Distinguished Contributor
    VB_Autocad_guy
    Posts: 136
    Registered: ‎07-24-2009

    Re: Database.Save "eFileSharingViolation"

    03-30-2012 04:32 PM in reply to: VB_Autocad_guy
    Thanks for the tip Norman!
    So the input parameter fileopenmode.

    I'm on autocad 2011 win xp.
    So this makes sense. It's working so far.
    Please use plain text.