.NET

Reply
Distinguished Contributor
VB_Autocad_guy
Posts: 136
Registered: ‎07-24-2009
Message 1 of 13 (1,010 Views)
Accepted Solution

Database.Save "eFileSharingViolation"

1010 Views, 12 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

 

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 2 of 13 (979 Views)

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
*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 3 of 13 (975 Views)

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
Distinguished Contributor
VB_Autocad_guy
Posts: 136
Registered: ‎07-24-2009
Message 4 of 13 (964 Views)

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.

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 5 of 13 (955 Views)

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
Distinguished Contributor
VB_Autocad_guy
Posts: 136
Registered: ‎07-24-2009
Message 6 of 13 (949 Views)

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

 

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 7 of 13 (935 Views)

Re: Database.Save "eFileSharingViolation"

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

Good to hear it

Cheers :smileyhappy:

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
*Expert Elite*
norman.yuan
Posts: 986
Registered: ‎04-27-2009
Message 8 of 13 (910 Views)

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)?

Moderator
Alexander.Rivilis
Posts: 1,406
Registered: ‎04-09-2008
Message 9 of 13 (904 Views)

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

Distinguished Contributor
VB_Autocad_guy
Posts: 136
Registered: ‎07-24-2009
Message 10 of 13 (892 Views)

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.
Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.