C# AutoCAD drawing file write protection errors in Batch loop.

C# AutoCAD drawing file write protection errors in Batch loop.

muckmailer
Collaborator Collaborator
2,087 Views
4 Replies
Message 1 of 5

C# AutoCAD drawing file write protection errors in Batch loop.

muckmailer
Collaborator
Collaborator

The following batch loop will work for as far as pulling up a group of drawings and saving them
when the  sample routine  "public static void AddCircle()" is flagged out. When I try to make drawing
changes using routine public static void AddCircle() the DrawingSaved routine give me drawing write
protection errors. How can I avoid drawing write protections errors in my batch loop.

 

//CODE     
        private void button5_Click(object sender, EventArgs e)
        {
            //Loop through each item in the array
            //foreach (string myStr in thisFormsArray)
            BatchLoop();
        }
  //Batch loop to open close drawings  
       public void BatchLoop()
        {
            foreach (String myStr in thisFormsArray)
            {
                MessageBox.Show(myStr);
                // Open the Drawing
                strFileName = myStr;
                OpenDrawing();
                //Add Drawing Changes code here.
                AddCircle();// My Sample Routine
                DrawingSaved();
                Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
                //Close drawing
                doc.CloseAndDiscard();
                  }
        }

          
       
        public static void DrawingSaved()
        {
        
        
               
                //Savedwg
                object obj = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("DBMOD");

            // Check the value of DBMOD, if 0 then the drawing has no unsaved changes
            if (System.Convert.ToInt16(obj) != 0)
            {
                if (System.Windows.Forms.MessageBox.Show("Do you wish to save this drawing?",
                                          "Save Drawing",
                                          System.Windows.Forms.MessageBoxButtons.YesNo,
                                          System.Windows.Forms.MessageBoxIcon.Question)
                                          == System.Windows.Forms.DialogResult.Yes)
                {
                    Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
                    acDoc.Database.SaveAs(acDoc.Name, true, DwgVersion.Current,
                                          acDoc.Database.SecurityParameters);
                }
                }
                 
            }
     //------------------------------------------- 
           public void OpenDrawing()
        {
           
           // strFileName = "C:\\campus.dwg";
                        //string strFileName = myStr;
            DocumentCollection acDocMgr = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;
            //Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            if (File.Exists(strFileName))
            {
                //acDocMgr.Open(strDwgName, false);
                DocumentCollectionExtension.Open(acDocMgr, strFileName);
            }
            else
            {
                acDocMgr.MdiActiveDocument.Editor.WriteMessage("File " + strFileName +
                                                               " does not exist.");
            }
        }
//---------------
          // public static void AddCircle(Document acDoc)
           public static void AddCircle()// My sample code
    {
               // Get the current document and database
              // Document acDoc = Application.DocumentManager.MdiActiveDocument;
               Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
               Database acCurDb = acDoc.Database;
               using (DocumentLock docLock = acDoc.LockDocument())
               {
               // Start a transaction
                   using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                   {
                       // Open the Block table for read
                       BlockTable acBlkTbl;
                       acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
                                                       OpenMode.ForRead) as BlockTable;

                       // Open the Block table record Model space for write
                       BlockTableRecord acBlkTblRec;
                      //Here******************************************************************
                       acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
                                                       OpenMode.ForWrite) as BlockTableRecord;
                        //Heres
                       // Create a circle that is at 2,3 with a radius of 4.25
                       using (Circle acCirc = new Circle())
                       {
                           acCirc.Center = new Point3d(2, 3, 0);
                           acCirc.Radius = 4.25;

                           // Add the new object to the block table record and the transaction
                           acBlkTblRec.AppendEntity(acCirc);
                           acTrans.AddNewlyCreatedDBObject(acCirc, true);
                       }

                       // Save the new object to the database
                       acTrans.Commit();
                   }// for lockdocument
               }
           }   
 

0 Likes
2,088 Views
4 Replies
Replies (4)
Message 2 of 5

augusto.goncalves
Alumni
Alumni
Call Database.CloseInput and make sure you Dispose the Database variable when you're done (try the 'using' keyword)
Regards,



Augusto Goncalves
Twitter @augustomaia
Autodesk Developer Network
0 Likes
Message 3 of 5

muckmailer
Collaborator
Collaborator

I have modified and cleaned my code.

As of now I can generate new drawings but I can't overwrite existing drawings.

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.IO;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.EditorInput;

// Added for Autocad

//using Autodesk.AutoCAD.Interop.AcadDocument;

using Autodesk.AutoCAD.Interop;

namespace MyAcadCSharpPlugin1

{

public partial class Form1 : Form

 

{

public Form1()

{

InitializeComponent();

Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

}

private string strFileName;

private string strDwgName;

private string[] thisFormsArray;

public string[] myArray

{

get

{

return thisFormsArray;

}

set

{

thisFormsArray = value;

}

}

private void button1_Click(object sender, EventArgs e)

{

FormDialog FormDialog = new FormDialog();

Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(FormDialog);

}

//on form2:

//create a method to show content of array:

public void ShowingArray(string[] array)

{

//1. or to pass to some control:

foreach (string item in array)

{

listBox1.Items.Add(item);

}

//2. or to show in meesageBox (or similar):

StringBuilder sb = new StringBuilder();

foreach (string item in array)

{

sb.AppendLine(item);

}

MessageBox.Show(sb.ToString());

}

 

private void Form1_Load(object sender, EventArgs e)

{

//Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

}

 

private string[] StArray;

 

private void button4_Click(object sender, EventArgs e)

{

ListDrawings();

}

public void ListDrawings()

{

//Loop through each item in the array

listBox1.Items.Clear();

foreach (string myStr in thisFormsArray)

{

MessageBox.Show(myStr);

listBox1.Items.Add(myStr);

}

}

public void DrawingChangeRoutine()

{

MessageBox.Show("Code Here");

AddCircle();// My Sample Routine

// SetLayerCurrent();

}

 

//Posted

private void button5_Click(object sender, EventArgs e)

{

//Loop through each item in the array

//foreach (string myStr in thisFormsArray)

BatchLoop();

}

//Batch loop to open close drawings

public void BatchLoop()

{

foreach (String myStr in thisFormsArray)

{

MessageBox.Show(myStr);

// Open the Drawing

strFileName = myStr;

OpenDrawing();

//Add Drawing Changes code here.

AddCircle();//Sample code routine to add circle in model space

//DrawingSaved();

SaveActiveDrawing1();

Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

//Close drawing

doc.CloseAndDiscard();

}

}

 

//-------------------------------------------

public static void SaveActiveDrawing1()

{

Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

int StrSaveNameLgh;

string strDWGName = acDoc.Name;

string StrSaveName;

string StrFileName;

string StrPathName;

String StrPath;

object obj = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("DWGTITLED");

//' Check to see if the drawing has been named

if (System.Convert.ToInt16(obj) == 0)

{

//' If the drawing is using a default name (Drawing1, Drawing2, etc)

//' then provide a new name

strDWGName = "c:\\MyDrawing1.dwg";

}

StrPathName = strDWGName;

StrPathName = StrPathName.Remove(StrPathName.Length - 4, 4);

StrFileName = Path.GetFileName(strDWGName);

StrSaveName = StrPathName + "\\" + "New-" + StrFileName;

MessageBox.Show(StrSaveName);

acDoc.Database.SaveAs(StrSaveName, true, DwgVersion.Current, acDoc.Database.SecurityParameters);

 

//acDoc.Database.SaveAs(strDWGName, true, DwgVersion.Current, acDoc.Database.SecurityParameters);

}

public void OpenDrawing()

{

 

DocumentCollection acDocMgr = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;

//Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

if (File.Exists(strFileName))

{

//acDocMgr.Open(strDwgName, false);

DocumentCollectionExtension.Open(acDocMgr, strFileName);

}

else

{

acDocMgr.MdiActiveDocument.Editor.WriteMessage("File " + strFileName +

" does not exist.");

}

}

//---------------

public static void AddCircle()//Sample code routine to add circle in model space

{

// Get the current document and database

// Document acDoc = Application.DocumentManager.MdiActiveDocument;

Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

Database acCurDb = acDoc.Database;

using (DocumentLock docLock = acDoc.LockDocument())

{

// Start a transaction

using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())

{

// Open the Block table for read

BlockTable acBlkTbl;

acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,

OpenMode.ForRead) as BlockTable;

// Open the Block table record Model space for write

BlockTableRecord acBlkTblRec;

acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],

OpenMode.ForWrite) as BlockTableRecord;

// Create a circle that is at 2,3 with a radius of 4.25

using (Circle acCirc = new Circle())

{

acCirc.Center = new Point3d(2, 3, 0);

acCirc.Radius = 4.25;

// Add the new object to the block table record and the transaction

acBlkTblRec.AppendEntity(acCirc);

acTrans.AddNewlyCreatedDBObject(acCirc, true);

}

// Save the new object to the database

acTrans.Commit();

}// for lock document

}

}

//---------------

}

}

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.IO;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.EditorInput;

// Added for Autocad

//using Autodesk.AutoCAD.Interop.AcadDocument;

using Autodesk.AutoCAD.Interop;

namespace MyAcadCSharpPlugin1

{

public partial class Form1 : Form

 

{

public Form1()

{

InitializeComponent();

Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

}

private string strFileName;

private string strDwgName;

private string[] thisFormsArray;

public string[] myArray

{

get

{

return thisFormsArray;

}

set

{

thisFormsArray = value;

}

}

private void button1_Click(object sender, EventArgs e)

{

FormDialog FormDialog = new FormDialog();

Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(FormDialog);

}

//on form2:

//create a method to show content of array:

public void ShowingArray(string[] array)

{

//1. or to pass to some control:

foreach (string item in array)

{

listBox1.Items.Add(item);

}

//2. or to show in meesageBox (or similar):

StringBuilder sb = new StringBuilder();

foreach (string item in array)

{

sb.AppendLine(item);

}

MessageBox.Show(sb.ToString());

}

 

private void Form1_Load(object sender, EventArgs e)

{

//Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

}

 

private string[] StArray;

 

private void button4_Click(object sender, EventArgs e)

{

ListDrawings();

}

public void ListDrawings()

{

//Loop through each item in the array

listBox1.Items.Clear();

foreach (string myStr in thisFormsArray)

{

MessageBox.Show(myStr);

listBox1.Items.Add(myStr);

}

}

public void DrawingChangeRoutine()

{

MessageBox.Show("Code Here");

AddCircle();// My Sample Routine

// SetLayerCurrent();

}

 

//Posted

private void button5_Click(object sender, EventArgs e)

{

//Loop through each item in the array

//foreach (string myStr in thisFormsArray)

BatchLoop();

}

//Batch loop to open close drawings

public void BatchLoop()

{

foreach (String myStr in thisFormsArray)

{

MessageBox.Show(myStr);

// Open the Drawing

strFileName = myStr;

OpenDrawing();

//Add Drawing Changes code here.

AddCircle();//Sample code routine to add circle in model space

//DrawingSaved();

SaveActiveDrawing1();

Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

//Close drawing

doc.CloseAndDiscard();

}

}

 

//-------------------------------------------

public static void SaveActiveDrawing1()

{

Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

int StrSaveNameLgh;

string strDWGName = acDoc.Name;

string StrSaveName;

string StrFileName;

string StrPathName;

String StrPath;

object obj = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("DWGTITLED");

//' Check to see if the drawing has been named

if (System.Convert.ToInt16(obj) == 0)

{

//' If the drawing is using a default name (Drawing1, Drawing2, etc)

//' then provide a new name

strDWGName = "c:\\MyDrawing1.dwg";

}

StrPathName = strDWGName;

StrPathName = StrPathName.Remove(StrPathName.Length - 4, 4);

StrFileName = Path.GetFileName(strDWGName);

StrSaveName = StrPathName + "\\" + "New-" + StrFileName;

MessageBox.Show(StrSaveName);

acDoc.Database.SaveAs(StrSaveName, true, DwgVersion.Current, acDoc.Database.SecurityParameters);

 

//acDoc.Database.SaveAs(strDWGName, true, DwgVersion.Current, acDoc.Database.SecurityParameters);

}

public void OpenDrawing()

{

 

DocumentCollection acDocMgr = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;

//Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

if (File.Exists(strFileName))

{

//acDocMgr.Open(strDwgName, false);

DocumentCollectionExtension.Open(acDocMgr, strFileName);

}

else

{

acDocMgr.MdiActiveDocument.Editor.WriteMessage("File " + strFileName +

" does not exist.");

}

}

//---------------

public static void AddCircle()//Sample code routine to add circle in model space

{

// Get the current document and database

// Document acDoc = Application.DocumentManager.MdiActiveDocument;

Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

Database acCurDb = acDoc.Database;

using (DocumentLock docLock = acDoc.LockDocument())

{

// Start a transaction

using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())

{

// Open the Block table for read

BlockTable acBlkTbl;

acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,

OpenMode.ForRead) as BlockTable;

// Open the Block table record Model space for write

BlockTableRecord acBlkTblRec;

acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],

OpenMode.ForWrite) as BlockTableRecord;

// Create a circle that is at 2,3 with a radius of 4.25

using (Circle acCirc = new Circle())

{

acCirc.Center = new Point3d(2, 3, 0);

acCirc.Radius = 4.25;

// Add the new object to the block table record and the transaction

acBlkTblRec.AppendEntity(acCirc);

acTrans.AddNewlyCreatedDBObject(acCirc, true);

}

// Save the new object to the database

acTrans.Commit();

}// for lock document

}

}

//---------------

}

}

 

0 Likes
Message 4 of 5

arcticad
Advisor
Advisor
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CopyFile
{
    class clsCopyFile
    {

        internal void ProcessFile(string strFullPath)
        {
            
            // This has been my work around for a long long time. 
            // Autocad may lock the file in use so we can do our processing in a copy and
            // then write the file back when finished, as long as the file is not already in use.
            // this will leave a copy in the temp folder. 
            // the temp file will be locked until you close AutoCAD.
            
      

            string strNewFullPath = "";
            // Copy File to Temp

            if (!IsFileinUse(strFullPath))
            {
                Copyfile(strFullPath, ref strNewFullPath);

                // Process File

                //  Write File back
                Copyfile(strNewFullPath, ref strFullPath);
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("Unable to Process file :" + strFullPath);

            }
        }

        /// <summary>
        /// Copy File that can be in use
        /// </summary>
        /// <param name="strFullPath"></param>
        /// <param name="strNewFullPath"></param>
        /// <returns></returns>
        public bool Copyfile(string strFullPath, ref string strNewFullPath)
        {
            try
            {
                strNewFullPath = System.IO.Path.GetTempFileName() + ".dwg";

                using (var inputFile = new FileStream(strFullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (var outputFile = new FileStream(strNewFullPath, FileMode.Create))
                    {
                        var buffer = new byte[0x10000];
                        int bytes;

                        while ((bytes = inputFile.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            outputFile.Write(buffer, 0, bytes);
                        }
                    }
                }
            }
            catch (System.Exception)
            {
                return false;
            }
            return true;
        }


        internal bool IsFileinUse(string path)
        {
            try
            {
                //Just opening the file as open/create
                using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate))
                {
                    //If required we can check for read/write by using fs.CanRead or fs.CanWrite                                 }
                    return false;
                }
            }

            catch (IOException)
            {
                return true;
            }
        }
    }

}
---------------------------



(defun botsbuildbots() (botsbuildbots))
0 Likes
Message 5 of 5

augusto.goncalves
Alumni
Alumni
Seems like you're missing the CloseInput... without that, AutoCAD will maintain the .dwg file locked.

Or you may try SaveAs and the replace, as described at http://adndevblog.typepad.com/autocad/2012/04/batch-process-in-memory-1.html
Regards,



Augusto Goncalves
Twitter @augustomaia
Autodesk Developer Network
0 Likes