Тема: Работа с несколькими файлами

Есть необходимость в программе, которая бы открывала dwg файлы, производила с ними определенные операции (извлечение информации о содержимом, очистка, сохранение под другим именем и т.п.). Начитавшись сайтов и форумов, сваял вот такое:

        [CommandMethod("Test1")]
        public void Test1()
        {
            DirectoryInfo rootDir = new DirectoryInfo(@"d:\dwg");
            System.IO.FileInfo[] files = null;
            files = rootDir.GetFiles("*.dwg");
            foreach (System.IO.FileInfo file in files)
            {
                Document activeDoc = acad.DocumentManager.MdiActiveDocument;
                Document dwgFile = acad.DocumentManager.Open(file.FullName);
                if (acad.DocumentManager.MdiActiveDocument != dwgFile)
                {
                    acad.DocumentManager.MdiActiveDocument = dwgFile;
                }
                Database dwgDB = acad.DocumentManager.MdiActiveDocument.Database;
                //Здесь будут какие-нибудь манипуляции с базой
                dwgFile.CloseAndDiscard();
                if (acad.DocumentManager.MdiActiveDocument != activeDoc)
                {
                    acad.DocumentManager.MdiActiveDocument = activeDoc;
                }
            }
        }

При отладке, когда программа доходит до строки

Document dwgFile = acad.DocumentManager.Open(file.FullName);

получаю ошибку:

LoaderLock was detected
Message: Попытка выполнения управляемого кода под блокировкой OS Loader. Запуск управляемого кода в пределах функции DllMain или функции инициализации образа может вызвать зависание приложения.

LoaderLock, конечно, можно отключить в Visual Studio, но при отладке тогда получаю сообщение:

mt.dll
A debugger has been found running in your system. Please, unload it from memory and restart your program

,
а при загрузке dll без отладки, открывается первый файл, а потом каждый раз вручную приходится активировать файл, который был открыт до запуска команды, чтобы программа продолжала работать.
Пробовал другой способ доступа к базе чертежей. Что-то типа этого:

            foreach (System.IO.FileInfo file in files)
            {
                Database db = new Database(false, true);
                HostApplicationServices.WorkingDatabase = db;
                db.ReadDwgFile(file.FullName, FileOpenMode.OpenForReadAndAllShare, false, null);
            }

В строке

db.ReadDwgFile(file.FullName, FileOpenMode.OpenForReadAndAllShare, false, null);

опять получаю ошибку "LoaderLock was detected". Что я делаю неправильно? Это как-то связано с блокированием документов? Конструкции типа

using (doc.LockDocument())

в моей программе нужны? Тестирую с Autocad 2014, если это имеет значение.

Re: Работа с несколькими файлами

Попробуй из немодальной формы:

        // in myPlugin.cs Initialize():
  Form frm = new Form1();
            Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(frm);


// in Form1.cs
        /// <summary>
        /// zoom to extents by Luis Esquivel
        /// </summary>
        /// <param name="db">drawing database</param>
        static public void ZoomExtents(Database db)
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Point3d max = db.Extmax;
            Point3d min = db.Extmin;
            Point2d max_2d = new Point2d(max.X, max.Y);
            Point2d min_2d = new Point2d(min.X, min.Y);
            ViewTableRecord view = new ViewTableRecord();
            view.CenterPoint = (min_2d + (max_2d - min_2d) / 2.0);
            view.Height = (max_2d.Y - min_2d.Y);
            view.Width = (max_2d.X - min_2d.X);
            doc.Editor.SetCurrentView(view);
            db.UpdateExt(true);
        }

      private void button1_Click(object sender, EventArgs e)
        {
            TestBatchOpenDocs();
        }

        [CommandMethod("bat1", CommandFlags.Session)]
        public void TestBatchOpenDocs()
        {
            string FolderPath = @"C:\Test\Blah\Blah";
            System.IO.DirectoryInfo rootDir = new System.IO.DirectoryInfo(FolderPath);
            System.IO.FileInfo[] files = null;
            files = rootDir.GetFiles("*.dwg");

            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;         
            Editor ed = doc.Editor;
            
            using (DocumentLock doclock = doc.LockDocument())
            {
                if (Convert.ToInt32(Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("dwgtitled"))==0)
                {
                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(
                        "Could not perform the batch operation\nfrom unnamed drawing\nOpen another drawing and try again");
                    return;
                }
                foreach (System.IO.FileInfo file in files)
                {
                    
                    string FileToOpen = file.FullName;

                    using (Database dwgDB = new Database(false, true))
                    {
                          // для А2014 синтаксис может быть другой:
                        dwgDB.ReadDwgFile(FileToOpen, System.IO.FileShare.ReadWrite, false, null);

                        System.Threading.Thread.Sleep(200);

                        HostApplicationServices.WorkingDatabase = dwgDB;

                            using (Transaction dwgTr = dwgDB.TransactionManager.StartTransaction())
                            {
                                //Здесь будут какие-нибудь манипуляции с базой 

                                BlockTable dwgBt = (BlockTable)dwgTr.GetObject(dwgDB.BlockTableId, OpenMode.ForRead);
                                BlockTableRecord DwgBtr = (BlockTableRecord)dwgTr.GetObject(dwgBt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                                Circle circ = new Circle(new Point3d(0, 0, 0), new Vector3d(0, 0, 1), 10.0);
                                circ.ColorIndex = 5;
                                circ.LineWeight = LineWeight.LineWeight053;
                                circ.Layer = "0";
                                DwgBtr.AppendEntity(circ);
                                dwgTr.AddNewlyCreatedDBObject(circ, true);
                                dwgTr.Commit();
                            }
                          
                           // пример Purge, ищи пример сам

                            //пример зума:
                            ZoomExtents(dwgDB);

                           // dwgDB.SaveAs(FileToOpen, false, DwgVersion.AC1800, dwgDB.SecurityParameters);
                            dwgDB.SaveAs(FileToOpen, false, DwgVersion.Current, dwgDB.SecurityParameters);
                        }

                    }
                }
            HostApplicationServices.WorkingDatabase = doc.Database;

            MessageBox.Show("Done");
            }

Re: Работа с несколькими файлами

Валерий Калинин пишет:

Есть необходимость в программе, которая бы открывала dwg файлы, производила с ними определенные операции (извлечение информации о содержимом, очистка, сохранение под другим именем и т.п.).
...
Тестирую с Autocad 2014, если это имеет значение.

1. Не нужно открывать документы (Document) - работай напрямую с базой данных (Database), считывая её с помощью метода Database.ReadDwgFile.
2. Самый быстрый вариант пакетной обработки чертежей - это использовать не acad.exe, но accoreconsole.exe (скорость обработки файлов возрастёт в несколько десятков раз).