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
Solved! Go to Solution.
Solved by norman.yuan. Go to Solution.
Solved by VB_Autocad_guy. Go to Solution.
Solved by Hallex. Go to Solution.
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'~
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'~
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.
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'~
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
Good to hear it
Cheers
~'J'~
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)?
Norman Yuan
Try:
using (Database db = new Database(false, true))
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Well, I'd think how an empty database is created (with noDocument argument being true/false) should not have effect on ReadDwgFile() method being called and the Database being saved as logically. But I could be wrong.
Anyway, I tested with
using (Database db = new Database(false, true))
The result were the same:
Acad2009 32bit: OK;
Acad2011 32bit: getting eFileSharingViolation exception
Acad2012 64bit: getting eFileSharingViolation exception
Since it is very unlikely this would have anything to do with 32/64bit, I'd think this is bug/break in Acad 19.xx (2010/11/12)
Except for OpenFileMode.OpenForreadAndWriteNoShare in ReadDwgFile() method, the other value of FileOpenMode (OpenForReadAndAllShare, OpenForreadAndReadShare and OpenTryForReadShare) seems OK.
So, if I'd avoid to use OpenFileMode.OpenForReadAndWriteNoShare, if I have to read dwg file into database in in the same time do not want the dwg file accessed by others.
Norman Yuan
norman.yuan wrote:
Since it is very unlikely this would have anything to do with 32/64bit, I'd think this is bug/break in Acad 19.xx (2010/11/12)
A small remark. 19.xx - is AutoCAD 2013 ..., but 18.xx is 2010,2011,2012
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn