Пакетная обработка файлов в NCAD 23.1 и монитор системных переменных
Задача: в фоновом режиме открыть энное количество файлов dwg, собрать оттуда (к примеру) список слоев и дальше все это богатство обрабатывать. Казалось бы, что может пойти не так? Но это ж наник, тут мины на каждом шагу раскиданы.
Так-то код не сильно сложный
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | using System; using Teigha.DatabaseServices; namespace GuNCad.Infrastructure { public sealed class WorkingDatabaseSwitcher : IDisposable { /// <summary> Переключение рабочей базы файла. Обязательно использование через <code>using</code> </summary> /// <param name="db">Устанавливаемая рабочей база чертежа</param> public WorkingDatabaseSwitcher(Database db) { _prevDb = HostApplicationServices.WorkingDatabase; _needToSwitch = !db.Equals(_prevDb); if (_needToSwitch) { HostApplicationServices.WorkingDatabase = db; } } public void Dispose() { if (_needToSwitch) { HostApplicationServices.WorkingDatabase = _prevDb; _prevDb = null; } } private Database _prevDb = null; private bool _needToSwitch; } } |
Ну и в основном модуле:
1 2 3 4 5 6 7 8 9 10 11 12 |
И вот тут проблема. В любой момент nanocad радостно разваливается. Причем использование try-catch проблему не решает. Простановка точек останова на собственных подписках на создание документа показала, что событие не срабатывает.
Похоже, ошибка на уровне ядра.
Пришлось прописывать логгер, благодаря которому и выяснилась причина:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 2025-09-09 16:37:08.4207 Start opening file 2025-09-09 16:37:09.5049 Ошибка обработки файла D:\Files\file01.dwg : Операция успешно завершена. at System.Drawing.Icon.Initialize(Int32 width, Int32 height) at System.Drawing.Icon..ctor(Icon original, Int32 width, Int32 height) at SystemVariable.ListViewImages.StorageDatabase(Size size) at SystemVariable.ListView.updateItemContent(Int32 indx) at SystemVariable.ListView.listView_LineUpdateUI(Object sender, ListViewLineLoadEventArgs e) at SysVarMonitor.ListView.updateItemsUI(Int32 start, Int32 end) at SysVarMonitor.ListView.set_LinesCount(Int32 value) at SystemVariable.ListView.loadItems() at SystemVariable.ControlPanel.loadListView() at SystemVariable.ControlPanel.LoadData(Data[] svdata) at SysVarMonitor.SysVarMonitorPaletteSet.SysVarChangedEvent(String name) at HostMgd.ApplicationServices.Application.raise_SystemVariableChanged(Object sender, SystemVariableChangedEventArgs value) at CApplicationReactorImpl.sysVarChanged(CApplicationReactorImpl* , OdDbDatabase* pDb, OdString* varName) at OdDbDatabase.readFile(OdDbDatabase* , OdStreamBuf* , Boolean , OdDbAuditInfo* , OdString* , Boolean ) at Teigha.DatabaseServices.Database.ReadDwgFile(String fileName, FileOpenMode mode, Boolean allowCPConversion, String password, Boolean bPartialLoad) at GuNCad.NCadCommands.DBaseExportImport.BatchExportToDBaseCmd.<>c__DisplayClass0_0.<GuBatchExportToDBaseCommand>b__0(String directoryName) in D:\Files\Source\Repos\<…>\BatchCmd.cs:line 111 2025-09-09 16:37:09.5178 D:\Files\file02.dwg 2025-09-09 16:37:10.0383 Start opening file |
Похоже, проблема только в наличии (и, возможно, активности) монитора системных переменных. Предполагаю, что при открытии другого файла монитор системных переменных начинает их мониторить на текущем документе, а не на активном, как это должно быть. А как выключить этот монитор - неясно: где и как хранятся эти настройки, я не знаю. Быстрый поиск по реестру ничего не показал; системной переменной, отвечающей за отображение монитора, нет; команда _.sysvarmonitor двойного назначения - если монитор есть, его закрывают, если его нет - открывают.
Надеюсь, в более поздних версиях проблема решена.
P.S. И еще неизвестно, какое поведение будет при открытой панели внешних ссылок. Будет прикольно, если и ее надо будет закрывать (и пока навскидку сказать, как отслеживать и ее состояние, я не знаю). Отбой - известно. Влияния не оказывает (по крайней мере в моих условиях)
В новых версиях еще немодальный диспетчер слоев появился.
Вангую тоже крови попьет
кстати
проверил на своей печати..
при открытом мониторе распечатал
1. открытые файлы
2. файлы из каталога
3. открытые и из каталога
нк 23,1 не вылетел
возможно эта тема требует более глубокого изучения??
Возможно, у тебя никакие переменные не менялись. Я просто реально ловил ошибки (лог снят с реальных файлов). Теперь бы выяснить, как можно узнать статус этого монитора (и как его выключить на время работы основного кода - желательно без вызова команд).
> Быстрый поиск по реестру ничего не показал; системной переменной, отвечающей за отображение монитора, нет;
Слишком быстро искал
SysVarMonitor
открыт: подраздел есть
HKEY_CURRENT_USER\SOFTWARE\Nanosoft\nanoCAD x64\23.1\Profiles\SPDS\Startup\SysVarMonitor
подраздела нет
HKEY_CURRENT_USER\SOFTWARE\Nanosoft\nanoCAD x64\23.1\Profiles\SPDS\Startup
нанодевы такие затейники
регорганайзер форевер
Я искренне полагал, что уж где-где, а в startup должны быть вещи, вызываемые на старте приложения. С другой стороны, удаление реестра не приводит к закрытию монитора (в принципе, предсказуемо). Придется все же командами обходиться (((
Спасибо
Чего там..
Прочитал подраздел , если есть
Запомнил
Закрыл монитор
Сделал дело открыл
Ага, угу. Только закрывать надо синхронно, чисто командой, и крайне желательно без оставления следов в ком.строке ))) Полчаса искал плюс-минус нормальный вариант