Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Андрей Бушман от 29-01-2014, 13:46:48

Название: Аудит средствами .NET API
Отправлено: Андрей Бушман от 29-01-2014, 13:46:48
AutoCAD 2009 SP3 Enu
AutoCAD 2014 SP1 Enu

Класс AuditInfo унаследован от DisposableWrapper в котором, в свою очередь присутствует метод со следующей сигнатурой:

Код - C# [Выбрать]
  1. public static DisposableWrapper Create(Type type, IntPtr unmanagedPointer, bool autoDelete);

В документации ObjectARX SDK (2009 и 2014) по данному методу (да и не только по нему, а почти по всем методам) класс DisposableWrapper не содержит никакой информации. Сооветственно приходится гадать о том, что за параметры следует ему передавать.

Код - C# [Выбрать]
  1. // db - экземпляр Database
  2. // Выполняю аудит базы данных чертежа
  3. Rtm.DisposableWrapper wrap = Db.AuditInfo.Create(typeof(Db.AuditInfo), db.GetRXClass().UnmanagedObject, true);
  4. Db.AuditInfo info = wrap as Db.AuditInfo;                      
  5. db.Audit(info); // Здесь получаю ошибку, завершающую работу AutoCAD.

Хотелось бы пояснений по данному методу - верно ли я его пытаюсь использовать?

В последней строке кода получаю ошибку, одну и ту же что в AutoCAD 2009, что в AutoCAD 2014 (см. скрины) с последующим немедленным умиранием AutoCAD.

Когда наконец-то наступит ImplementedAlready?
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 29-01-2014, 18:30:48
Когда наконец-то наступит ImplementedAlready?
Вот уж не знаю. В чистом ObjectARX тоже это метод не реализован. Я не проверял, но метод DBObject.Audit вроде бы реализован, т.е. можно попробовать последовательно вызвать его для каждого объекта/примитива. Ну и альтернативный способ - вызов ActiveX/COM метода AcadDocument.AuditInfo.
Название: Re: Аудит средствами .NET API
Отправлено: bargool от 26-02-2015, 11:28:14
А как пользоваться DBObject.Audit? Какие ограничения? У меня любой из приведённых ниже методов падает с System.AccessViolationException при запуске в шаблоне из вложения к сообщению (и на любом файле, сделанном на основе данного шаблона). При этом команда audit не выдаёт никаких ошибок в файлах.
При этом, на стандартном акадовском шаблоне отрабатывает спокойно.
Autocad 2014x64
Код - C# [Выбрать]
  1. [CommandMethod("testaudit")]
  2. public void TestAudit()
  3. {
  4.     Database db = HostApplicationServices.WorkingDatabase;
  5.     DisposableWrapper wrap = AuditInfo.Create(typeof(AuditInfo), db.GetRXClass().UnmanagedObject, true);
  6.     AuditInfo ai = wrap as AuditInfo;
  7.     using (Transaction tr = db.TransactionManager.StartTransaction())
  8.     {
  9.         BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  10.         foreach (var id in bt.Cast<ObjectId>())
  11.         {
  12.             DBObject dbo = tr.GetObject(id, OpenMode.ForWrite);
  13.             dbo.Audit(ai);
  14.         }
  15.         tr.Commit();
  16.     }
  17. }
  18.  
  19. [CommandMethod("testaudit2")]
  20. public void TestAudit2()
  21. {
  22.     Database db = HostApplicationServices.WorkingDatabase;
  23.     using (Transaction tr = db.TransactionManager.StartTransaction())
  24.     {
  25.         BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  26.         foreach (var id in bt.Cast<ObjectId>())
  27.         {
  28.             DBObject dbo = tr.GetObject(id, OpenMode.ForWrite);
  29.             DisposableWrapper wrap = AuditInfo.Create(typeof(AuditInfo), dbo.GetRXClass().UnmanagedObject, true);
  30.             AuditInfo ai = wrap as AuditInfo;
  31.             dbo.Audit(ai);
  32.         }
  33.     }
  34. }
Название: Re: Аудит средствами .NET API
Отправлено: Андрей Бушман от 26-02-2015, 11:37:48
А как пользоваться DBObject.Audit?
Аудит можно глянуть тут (http://adn-cis.org/api-dlya-proverki-chertezha-novyij-v-autocad-2015.html) (правда это для 2015-го). Правда по ссылке используется Database.Audit. Попробуй в своём коде выполнить блокировку документа, прежде чем выполнять аудит (я не утверждаю, что это поможет, просто это первое, что приходит на ум по теме). Однако я  не исключаю, что для версий более ранних, чем 2015, функционал аудита мог быть ещё не реализован, как я уже указывал в первом сообщении темы касательно Database.Audit.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 26-02-2015, 12:19:58
У меня любой из приведённых ниже методов падает с System.AccessViolationException при запуске в шаблоне из вложения к сообщению (и на любом файле, сделанном на основе данного шаблона).
На других не падает? Проанализируй на чем именно падает. Как я понял ты проверяешь только BlockTableRecord'ы.
Название: Re: Аудит средствами .NET API
Отправлено: bargool от 26-02-2015, 12:23:40
Андрей Бушман, нужен 2014..
Александр Ривилис, у меня тут все файлы сделаны на основе этого шаблона, так что на других реальных файлах не проверял. Проверял на стандартном acadiso.dwt, там не падает.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 26-02-2015, 12:30:50
Вообще говоря использование этого метода нигде не описано. Зато в COM/ActiveX есть метод AcadDocument.AuditInfo
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 26-02-2015, 14:28:52
P.S.: Кстати в коде написана полная ерунда. Я когда-то не заметил эту ерунду у Андрея и она расползлась. ;)
Метод:
Код - C# [Выбрать]
  1.  public static DisposableWrapper Create(Type type, IntPtr unmanagedPointer, bool autoDelete);
используется для создания управляемого объекта из неуправляемого. Т.е. в качестве unmanagedPointer необходимо передать указатель на объект неуправляемого класса AcDbAuditInfo. Но у нас такого объекта нет. А передавать указатель на Database или на DbObject - это совершенно бессмысленно и точно может привести к Fatal Error.
Можно конечно попытаться через P/Invoke вызвать конструктор AcDbAuditInfo, но насколько мне известно это сделать невозможно: http://stackoverflow.com/questions/2354152/p-invoke-a-purely-c-library
Название: Re: Аудит средствами .NET API
Отправлено: Андрей Бушман от 26-02-2015, 14:35:40
Кстати в коде написана полная ерунда. Я когда-то не заметил эту ерунду у Андрея и она расползлась.
Заметили и до сих пор молчали? Минус один вам в карму за такое! :)
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 26-02-2015, 14:37:29
Заметили и до сих пор молчали?
Только что заметил, а не тогда, когда ты написал этот код и создал эту тему на форуме. Читай внимательно моё сообщение. :)
Название: Re: Аудит средствами .NET API
Отправлено: bargool от 26-02-2015, 16:49:21
Вообще, именно такую конструкцию я видел в сообщении от 2010 года
http://forums.autodesk.com/t5/net/help-with-auditinfo-constructor/m-p/2744515#M20323
Жалко, caddzone.com ушел в небытие, туда Тони дал ссылку на своё решение..
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 26-02-2015, 16:58:03
Вообще, именно такую конструкцию я видел в сообщении от 2010 года
http://forums.autodesk.com/t5/net/help-with-auditinfo-constructor/m-p/2744515#M20323
Просто ему никто не сказал, что там написана ерунда.
Жалко, caddzone.com ушел в небытие, туда Тони дал ссылку на своё решение..
Решение заключалось в синхронном выполнении команд для файлов. Насколько я помню там был код через ActiveX.
Название: Re: Аудит средствами .NET API
Отправлено: bargool от 02-03-2015, 13:58:07
Крыша едет неспеша..
Можно ли получить AcadDocument из Database, если она открыта через ReadDwgFile?
В том смысле, что бы использовать AcadDocument.AuditInfo
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 03-03-2015, 01:48:58
Можно ли получить AcadDocument из Database, если она открыта через ReadDwgFile?
Увы. Я потестировал и пришел к неутешительному результату, что это сделать нельзя:
Код - C# [Выбрать]
  1.     [CommandMethod("Test")]
  2.     public void Test()
  3.     {
  4.       Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  5.       Database dbOld = HostApplicationServices.WorkingDatabase;
  6.       // Обрати внимание на второй false !!!
  7.       using (Database db = new Database(false, false))
  8.       {
  9.         db.ReadDwgFile(@"C:\testfile.dwg", FileShare.ReadWrite, false, "");
  10.         Document doc = Application.DocumentManager.GetDocument(db);
  11.         if (doc != null)
  12.         {
  13.           object aDoc = doc.GetAcadDocument();
  14.           if (aDoc != null)
  15.           {
  16.             aDoc.GetType().InvokeMember("AuditInfo",
  17.               BindingFlags.InvokeMethod, null,
  18.               aDoc, new object[] {true});
  19.           }
  20.         }
  21.       }
  22.     }
  23.  

doc у меня возвращает текущий чертеж и соотвественно Audit выполняется для него.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 03-03-2015, 02:30:23
На всякий случай отправил запрос в ADN DevHelp. Мне кажется странным, что есть опция для создания Database с попутным созданием документа и при этом документ найти нельзя.
Название: Re: Аудит средствами .NET API
Отправлено: Андрей Бушман от 03-03-2015, 10:43:01
Мне кажется странным, что есть опция для создания Database с попутным созданием документа и при этом документ найти нельзя.
А где вы видите эту опцию, если не секрет?

doc у меня возвращает текущий чертеж и соотвественно Audit выполняется для него.
Но ведь именно это поведение и обозначено в документации... Какой ответ ожидаете от ADN?

Сигнатура конструктора:
Код - C# [Выбрать]
  1. public Database(
  2.     [MarshalAs(UnmanagedType.U1)] bool buildDefaultDrawing,
  3.     [MarshalAs(UnmanagedType.U1)] bool noDocument
  4. );

А вот описание второго параметра:
Цитата: ObjectARX 2015 SDK
[MarshalAs(UnmanagedType.U1)][MarshalAs(UnmanagedType.U1)] bool noDocument  System.Boolean specifying whether or not to associate this database to the current document

Описание первого параметра тоже не особо похоже на то, о чём вы пишете:

[MarshalAs(UnmanagedType.U1)] bool buildDefaultDrawing - System.Boolean specifying whether or not to build an empty object 
Под "empty object" я понимаю пустую Database.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 03-03-2015, 11:18:12
Я несколько иначе трактую второй (именно второй) параметр. Если бы шла ассоциация созданной базы с текущим чертежом, то Audit сработал бы с ним. В действительности он у меня проверял пустой новый чертеж. Но давай дождемся комментария из ADN DevHelp.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 05-03-2015, 11:30:38
Первый комментарий от ADN DevHelp пришёл. В первом приближении они не видят возможность выполнять Audit в чертеже открытом через Database.ReadDwgFile, но обещали проконсультироваться в Eng Team.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 05-03-2015, 14:37:15
Итак. Окончательный вердикт от ADN DevHelp. Audit невозможен в чертеже, который не открыт в редакторе AutoCAD в версиях предшествующий AutoCAD 2015.
Название: Re: Аудит средствами .NET API
Отправлено: alexb от 29-06-2015, 20:25:27
Is there a way of extracting information after the Audit run (i.e. number of errors found, number fixed, etc)?
I am on A2012, so database.audit() is not available.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 29-06-2015, 20:36:50
Is there a way of extracting information after the Audit run (i.e. number of errors found, number fixed, etc)?
I am on A2012, so database.audit() is not available.
Shalom Alex! What about asking in Russian? ;)
There is only one way is hack commandline output and read it. As I know it is possible only with ObjectARX:
Trapping The Output From The AutoCAD Text Screen / Command Prompt (http://adndevblog.typepad.com/autocad/2012/09/trapping-the-output-from-the-autocad-text-screen-command-prompt.html)
 
Название: Re: Аудит средствами .NET API
Отправлено: alexb от 30-06-2015, 00:14:18
About Asking what in Russian?
Hi Alexander
Can't. Despite my name, I don't speak Russian.
About Asking what in Russian?
Hi Alexander! Sorry, despite my name I don't speak Russian. So, to use your site I have to translate back and forth between Russian and English, but it's worth the effort.
About the Audit output: one can also redirect the output to a log file and then parse it. I think I also saw a method of subclassing the text window written in C#, but I can't find it.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 30-06-2015, 00:39:51
Hi Alexander! Sorry, despite my name I don't speak Russian.
Sorry.
About the Audit output: one can also redirect the output to a log file and then parse it. I think I also saw a method of subclassing the text window written in C#, but I can't find it.
To use sample C++ (with using AcDbHostApplicationServices) a lot easier.
Название: Re: Аудит средствами .NET API
Отправлено: alexb от 30-06-2015, 07:37:44
To use sample C ++
What sample are you referring to?
I was thinking about writing a C++ method in ARX which accepts a pointer to a Database, executes AuditInfo on that db, retrieves the results from the AuditInfo and returns them to caller.
BTW, I am using Google Chrome Translate and the english text I write displays OK only when I choose to show the page in original, otherwise it changes the words' order, capitalizes some of them, etc. I hope you can understand me despite Goggle's interference.
Название: Re: Аудит средствами .NET API
Отправлено: Андрей Бушман от 30-06-2015, 10:32:31
BTW, I am using Google Chrome Translate and the english text I write displays OK only when I choose to show the page in original, otherwise it changes the words' order, capitalizes some of them, etc. I hope you can understand me despite Goggle's interference.
In my opinion, the Google Translate translates worse than http://www.translate.ru/#!/Computer/ Therefore I prefer to use http://www.translate.ru/#!/Computer/
Название: Re: Аудит средствами .NET API
Отправлено: Андрей Бушман от 30-06-2015, 11:02:11
2 alexb
It will not help to you with AutoCAD, but maybe interesting like the common info...

*CAD .NET developers consider AutoCAD .NET API as classical, usually. But the shortcomings of implementation of AuditInfo from Autodesk are strong. Therefore for this method another implementation was made by ODA developers. Their implementation is more convenient and natural: AuditInfo is a class for audit operation settings and has the audit result info also.

I haven't hope Autodesk will do the same, because their current "new" implementation (http://adndevblog.typepad.com/autocad/2014/03/audit-api-new-in-autocad-2015.html) is horrible also.

For comparring of AuditInfo idea implementation (these are pieces of my old code):
Извините, вам запрещён просмотр содержимого спойлеров.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 30-06-2015, 11:43:02
What sample are you referring to?
http://adndevblog.typepad.com/autocad/2012/09/trapping-the-output-from-the-autocad-text-screen-command-prompt.html
This sample can help you understand how to read commandline info.
Название: Re: Аудит средствами .NET API
Отправлено: Андрей Бушман от 30-06-2015, 14:43:57
I added code sample in my previous message for comparring of AuditInfo idea implementation.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 30-06-2015, 16:07:30
Андрей Бушман
В очередной раз напоминаю, что мы договаривались на этом форуме не упоминать клоны AutoCAD и всё что касается доступа к dwg-файлам любыми альтернативными (официально не одобренными Autodesk) методами.
Название: Re: Аудит средствами .NET API
Отправлено: Андрей Бушман от 30-06-2015, 16:52:14
There is only one way is hack commandline output and read it. As I know it is possible only with ObjectARX:
Trapping The Output From The AutoCAD Text Screen / Command Prompt (http://adndevblog.typepad.com/autocad/2012/09/trapping-the-output-from-the-autocad-text-screen-command-prompt.html)

Цитата: Philippe Leefsma
AutoCAD makes an assumption about its standard host application services object - it will cast the pointer to a non-published, derived class. It is therefore a matter of only replacing the
object as long as is absolutely necessary.

This approach has also not been thoroughly tested for all commands; therefore, it should be used with caution and will need more complete testing on commands not tested by this sample.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 30-06-2015, 17:48:00
Philippe Leefsma
Я не собираюсь с ним спорить. Переключение на Custom AcDbHostApplicationServices будет делаться только на время команды Audit.
Название: Re: Аудит средствами .NET API
Отправлено: Андрей Бушман от 30-06-2015, 17:57:13
Я не собираюсь с ним спорить. Переключение на Custom AcDbHostApplicationServices будет делаться только на время команды Audit.
Я не о споре. Где гарантия того, что во время работы Audit, внутри API самого AutoCAD не произойдёт (в той или иной ситуации) попытка обращения к тому самому non-published, derived class? Если я верно понял Philippe Leefsma - таких гарантий как раз и нет... Т.е. это как подбрасывание монетки: в одном случае всё может пройти успешно (попытка обращения не производилась), а в другом (попытка обращения имеется) - накрыть медным тазом AutoCAD.

There is only one way is hack commandline output and read it. As I know it is possible only with ObjectARX:
Trapping The Output From The AutoCAD Text Screen / Command Prompt
Вряд ли возможность воспользоваться наследованием, и так разрешённым в ObjectARX, с последующим вызовом штатной функции acdbSetHostApplicationServices стоит называть хаком :) Вот если бы был продемонстрирован способ решения через хуки - тогда да (причём такой пример было бы даже очень интересно почитать)...
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 30-06-2015, 18:56:13
Вот если бы был продемонстрирован способ решения через хуки - тогда да (причём такой пример было бы даже очень интересно почитать)
Зачем хуки в данном случае? Тем более что окно CommandLine может быть вообще закрыто, так что "хукать" будет нечего. Можно просто перед _Audit сделать _LogFileOn, после _Audit сделать _LogFileOff и прочитать log-файл. Самый простой способ.
Название: Re: Аудит средствами .NET API
Отправлено: Андрей Бушман от 30-06-2015, 19:04:04
окно CommandLine может быть вообще закрыто, так что "хукать" будет нечего
Я предполагал, что обозначенное окно связано с некоторым потоком (stream), в следствии чего работать было бы целесообразней именно с потоком, а не с окошком. А операции, обозначенные Филипом воспринимал как обёртки над штатными функциями записи в поток.

Можно просто перед _Audit сделать _LogFileOn, после _Audit сделать _LogFileOff и прочитать log-файл. Самый простой способ.
Можно.
Название: Re: Аудит средствами .NET API
Отправлено: Александр Ривилис от 30-06-2015, 19:10:34
А операции, обозначенные Филипом воспринимал как обёртки над штатными функциями записи в поток.
Вот этот поток только так (через AcDbHostApplicationServices) и можно хукать.