Command: NETLOAD
Сборка "E:\_Profiles\Visual Studio 2010\Projects\MyHelp\MyHelp\bin\Debug\MyHelp.dll" успешно загружена.
Файл "E:\_Profiles\Visual Studio 2010\Projects\MyHelp\MyHelp\bin\Debug\MyHelp.chm" найден. Регистрация раздела справки выполнена.
Command: THROUGHATTRIBUTE
Нажмите клавишу F1 для открытия нужного раздела справочной системы.
: *Cancel*
Command: *Cancel*
Command: THROUGHACEDSETFUNHELP
Нажмите клавишу F1 для открытия нужного раздела справочной системы.
: *Cancel*
Command: THROUGHPROCESS
Command: *Cancel*
Не очень понятно откуда берется *Cancel*.Я на Esc тыкал =) , запускал в режиме отладке из студии, студия вроде бы без админских прав запускается (соответствующие галочки сняты)
p.S.: Хотел уточнить - запуск у тебя от имени Администратора идет или от обычного пользователя?
ACAD 2010 Win7*32 - как и у автора - ThroughProcess - вызывает нужную справку, в остальных случаях по F1 - выскакивает автокадная.Дима. А что в командной строке при загрузке dll?
THROUGHATTRIBUTE - автокад ругается что такого файла нету, после загружает свою справкуРешение, конечно через ж@пу, но всё же попробуй для этого случая на время добавить запись в каталоги поиска AutoCAD (предполагаю, что может сработать).
сборка на рабочем столе, файл справки в папке автокада:Это логично, поскольку данная команда ищет справку в каталоге сборки (в коде прописано).
...
THROUGHPROCESS - ругается что не удается открыть справку
AutoCAD 2009...На уровне подозрения - попробуй проверить компиляции под разные .Net (2.0 и 3.5).
Предлагаю радикальное средство - отказаться от встроенных методов работы со справкой AutoCAD, т.е. сделать собственную реализацию.а может всё же, для начала, попытаться побеспокоить adn по теме, дабы зря не изобретать велосипеды?
а может всё же, для начала, попытаться побеспокоить adn по теме, дабы зря не изобретать велосипеды?Нет. Про AutoCAD 2009 и 2010 я им рассказывать не буду, а в последних трёх версиях пока только у тебя возникла проблема. Так что займемся велосипедом.
Я подумал, что иногда велосипед лучше, что встроенный инструмент. Во всяком случае ты можешь его контролировать и понимать как оно работает.Не спорю, однако то, что вы боитесь "барина побеспокоить" способствует тому, что постепенно API скатывается в состояние "ничего не знаю, на моём компьютере работает", вынуждая сторонних программистов писать свои "велосипеды". Польза такого API стремится к нулю, ибо надеяться на "авось и у пользователя заработает" - это хреновая надежда. Ну, не хотите "тревожить боярина по пустякам" - не тревожьте - дело ваше, хотя меня и раздражает подобное отношение, как вы понимаете... На мой взгляд, ADN должен знать об обозначенной проблеме, дабы потом не округляли глаза, мол "а нам никто и не сообщал".
Очень не нравится обилие использования PInvoke, но на безрыбье, как говорится, и рак лебедь...Их тут как раз не слишком много. Просто я решил не пользоваться препроцессором. Фактически вызываются две функции, но в зависимости от разрядности и версии AutoCAD каждая из них имеет по четыре сигнатуры. Итого имеем восемь описиний функций для P/Invoke
Нет. Про AutoCAD 2009 и 2010 я им рассказывать не буду, а в последних трёх версиях пока только у тебя возникла проблемаАлександр, это я ни в коей мере не Вам - мысли вслух. Я считаю что если производитель не поддерживает более свой продукт (я не имю в виду, что, например, он обязан выпускать заплатки под новые версии операционок, либо обновления других компонентов - тот функционал который декларировался на момент выпуска) - то данную версию продукта надо законодательно признавать бесплатной и свободной к распостранению.
то данную версию продукта надо законодательно признавать бесплатной и свободной к распостранению.Ну если кому-то из "власть предержащих" (страну не уточняем, так как мы ведем абстрактный диалог) придёт в голову выполнить твою рекомендацию, то:
Администрация позиционирует этот форум, как форум технической поддержки и помощи программистам. Давайте этой позиции и придерживаться. Луше проверь как у тебя работает мой код.Хотелось сказать свои соображения, но правила есть правила. Ваш код проверил - работает(2010).
ИХМО при таком количестве нативного кода никак не могу назвать данную конструкцию целесообразной - если только делать отдельную dll с соотвествующими классами.В действительности нативного кода там чуть-чуть, но по поводу отдельный сборки и/или отдельного пространства имён для класса Helper - я полностью согласен.
1. Версия AutoCAD должна быть одной из последних трёх, на которой этот баг воспроизводится.
2. Была бы возможность описать ситуацию, в которой этот баг однозначно воспроизводится.Существует такая компания: Wintellect (http://www.wintellect.com/). Джон Роббинс, один из учредителей этой компании, в своей книге "Отладка приложений для Microsoft .NET" пишет (стр. 46-47):
Самый важный шаг процесса отладки - первый: воспроизведение ошибки. Иногда это трудно, иногда даже невозможно, но если вы не можете воспроизвести ошибку, то, вероятно, не сможете устранить её. Пытаясь повторить ошибку, иногда приходится прибегать к крайним мерам. Однажды в моём коде встретилась ошибка, которую я не мог воспроизвести, просто запустив программу. Однако мне в голову пришла мысль об определённых состояниях данных, которые могли вызывать ошибку, поэтому я запустил программу в отладчике и ввёл данные, необходимые для воспроизведения ошибки, прямо в память. Это сработало.Откровенно говоря, меня неприятно удивляет тот факт, что вас приходится уговаривать о том, чтобы принять меры к устранению обозначенного бага. Такое ощущение, что ваша задача - препятствовать регистрации того, что не удаётся воспроизвести сходу, мол "не вижу ошибку на своём компе, значит её не существует, а пользователь - да и хрен на него, это у него что-то не так с компьютером". В обозначенной мною выше книге написано, что сотрудников, подобным образом относящихся к работе они увольняют, поскольку компания заинтересована в качестве результатов своей работы. Судя по тому, как вы упираетесь - у автодеска иные приоритеты.
...
Моё определение заключается в повторении ошибки на отдельно взятой машине один раз в течение 24-часового периода. Этого для моей компании достаточно, чтобы приняться за работу над ошибкой. Почему? Всё просто. Если вы сможете получить её на одной машине, то сможете добавить 30 машин и повторить ошибку 30 раз. При воспроизведении ошибки многие люди делают ещё одну: они не используют в процессе отладки максимально возможное количество машин.
...
Даже если вы не можете воспроизвести ошибку, её всё равно необходимо занести в систему отслеживания ошибок. Если я встречаю ошибку, которую не могу повторить, я обязательно регистрирую её в системе, но оставляю примечание, говорящее, что воспроизвести её не удалось. Таким образом, если за эту часть кода несёт ответственность другой инженер, то он, по крайней мере, будет знать, что что-то не так. Регистрируя ошибку, которую не удалось воспроизвести, нужно как можно лучше описывать её. Если вы дадите достаточно хорошее описание, то это поможет вам или другому инженеру в итоге устранить проблему. Чрезвычайно важно дать всестороннее описание ошибки, так как это позволит заметить взаимосвязи между различными отчётами о неповторяемых ошибках и обнаружить определённые шаблоны в поведении ошибок.
Последнее, о чём я хочу сказать, рассуждая о воспроизведении ошибок - очень редко ошибки удаётся воспроизвести на машине, где вы осуществляете разработку. Причина заключается в том, что на машине для разработки у вас есть различные инструменты и процессы, которых нет на машине для обычного выполнения, или, что ещё хуже, вы можете работать в системе под учётной записью с правами администратора. Учитывая, что и Microsoft и VMWare предоставляют свои виртуальные среды, нет никаких оправданий отсутствию на вашей машине виртуальной версии среды выполнения с возможностью удалённой отладки. Необходимо воспроизводить ошибки на виртуальной машине, поскольку это даёт лучшие шансы на обнаружение точных шаблонов.
Как видим, во всех трёх случаях результат один и тот же.Вот с этого нужно было и начинать. Пока я прихожу к выводу, что это глюк в AutoCAD x86 в Windows 7 x86. В таком виде уже можно и отправить в ADN DevHelp.
В таком виде уже можно и отправить в ADN DevHelp.ИХМО, в таком не надо, формально баг .NetApi есть только в виде не работающей перегрузке аттрибута CommandMethod, что не работает вызов нативный acedSetFunHelp - это к .NetApi никак не относится (хоть и понятно, что, скорее всего, дело именно в нативной части). Если каким-то чудесным образом окажется, что из-под ARX acedSetFunHelp в указанных версиях будет работать, то по чему не работает "внешний" вызов - это реально не их забота (это не штатный вызов функции - с таким-же успехом можно спросить почему я на дельфи не могу arx писать - не предназначен). Если и из-под ARX сей метод не заработает(что скорее всего) - то это уже и оформлять как баг - и отправлять - там думаю и аттрибут заработает.
Если и из-под ARX сей метод не заработает(что скорее всего) - то это уже и оформлять как баг - и отправлять - там думаю и аттрибут заработает.Собственно именно это я и собирался сделать.
з.ы. по части .NetApi - если только писать helloword c соответствующими аттрибутами в CommandMethod...чем выше обозначенные варианты не "helloword"?
по в моем понимании это просто не очень культурноУ меня понимание иное. В коде показано, что в поисках источника проблемы были испробованы разные варианты решений. Это экономит время на разбирательство.
Итак первый вариант. Прошу тестировать:Этот .NET код работает (проверял в AutoCAD 2013 x86 Enu). Но! тот, который "Нажмите F1 для ThroughProcess:" открывает как то, что нужно (пользовательский раздел пользовательской справки), так и окно попытки лезть за справкой в инет (при первом вызове TestF1). При последующих вызовах TestF1 всё работает как надо.
Сделал тестовый пример на ObjectARX для AutoCAD 2013 и 2014 x86У меня оба обозначенных варианта щимятся за справкой в Интернет. Запускал в AutoCAD 2013 x86. В обоих случаях в консоль AutoCAD выводится правильное полное имя CHM файла справки.
Загружать при помощи _APPLOAD.
Команды для проверки:
ThroughAcedSetFunHelp - должна по нажатию F1 появится справка с пунктом ThroughAcedSetFunHelp
ThroughAcedHelp - должна появится сразу справка с пунктом ThroughAcedSetFunHelp
ACAD 2010 Win7*32 - как и у автора - ThroughProcess - вызывает нужную справку, в остальных случаях по F1 - выскакивает автокадная.
Работают однако оба варианта. Надо писать helloword на аттрибут ComandMethod (мне сейчас не до того). Видимо косяк похитрее.Нет. Тут уже дело и не в атрибуте, т.к. P/Invoke для acedHelp у тебя не сработало, а acedHelp из ObjectARX сработало. Нужно передохнуть и подумать.
з.ы. Андрей - убери все лишнее.Во первых: я не знаю F# и ты об этом в курсе, так что подправить твой код я не смогу. Полагаю, что смогу вставить твой текущий код в новый проект и собрать его лишь под AutoCAD 2009-2012.
так что подправить твой код я не смогу...Я как-бы намекал, что вызов работает, "подреж" свой код как раз таки на "новые версии" и пр. - может ошибка там.
твой код не будет работать в AutoCAD версий более новых
Отлично. Теперь есть что отсылать в ADN DevHelp.Запускал ваш ARX в AutoCAD 2013-м x86 с правами администратора - результат аналогичен описанному мною для запуска из под обычного юзера.
И чтоб окончательно все запутать, я таки написал helloword в виде лисп функции (ихмо так проверять гораздо удобней):На вкус и цвет все фломастеры разные - мне так не удобней.
и здесь появляется нужная справка - то есть вызов работаетПодправил твой код так, чтобы он заработал под AutoCAD 2015 x86 (заменил acad.exe на accore.dll и переименовал acedSetFunHelp на _acedSetFunHelp):
з.ы. Андрей - убери все лишнее.
з.з.ы да если выбрать другой топик - тоже работает корректно.
module dimas_help_sample
open Autodesk.AutoCAD.ApplicationServices
open Autodesk.AutoCAD.Runtime
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open System.Runtime.InteropServices
[<DllImport("accore.dll",CallingConvention=CallingConvention.Cdecl,
CharSet=CharSet.Auto)>] extern int _acedSetFunHelp(string,string,string)
let Rb=function
|null->[]
|(rb:ResultBuffer)->rb.AsArray()|>Array.toList
let (|AcStr|_|) (x:TypedValue)=
match enum<LispDataType>(x.TypeCode|>int) with
|LispDataType.Text->x.Value:?>string|>Some
|_->None
[<LispFunction "TestHelp">]
let TestHelp arg=arg|>Rb|>function
|[AcStr fname;AcStr path;AcStr topic]->_acedSetFunHelp(fname,path,topic)|>ignore
|_->"Ошибка аргумента - (testhelp имя_функции путь глава)"
|>Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage
Результат показан во вложенном файле, как видишь - у меня твой вариант пытается открыть родную справку автокада из инета.На вкус и цвет все фломастеры разные - мне так не удобней.Тоже правда, я из соображений что отладка так точно быстрей (поменять аргументы не требует перезагрузки), но пожалуйста могу и командой (в 2010x86 работает - проверял):
Хм. А в 2009-ом работает?Не до конца...
(testhelp "example" "C:/public/ACAD/Debug/dimas_help_sample/myhelp.chm" "About")Второй:
(defun c:example()(getpoint "Есть время на F1"))
EXAMPLE
(testhelp "example" "C:/public/ACAD/Debug/dimas_help_sample/myhelp.chm" "ThroughAttribute")Пользовательская справка открывается, но в обоих случаях текущим является первый раздел About (см. вложение).
(defun c:example()(getpoint "Есть время на F1"))
EXAMPLE
Я не уверен, да и 2015 у меня нет, а точно acedSetFunHelp не скомпилирует (нужен именно _acedSetFunHelp) ? Проверь - если не сложно.C++ компилятор от Microsoft для функций x86 теперь автоматом добавляет префикс в виде подчёркивания. Такой вот "подарочек" программистам... Поскольку я использую x86, то наличие обозначенного префикса (начиная с версии AutoCAD 2015) является необходимым.
__stdcallисточник здесь (http://msdn.microsoft.com/ru-ru/library/zxk0tw93.aspx).
Соглашение об оформлении имен
К имени добавляется префикс в виде символа подчеркивания (_). После имени добавляется знак @, за которым следует количество байтов (в десятичном представлении) в списке аргументов. Поэтому функция, объявленная как int func( int a, double b ) декорируется следующим образом: _func@12
...
На процессорах ARM и 64-разрядных процессорах соглашение __stdcall принимается и игнорируется компилятором;
C++ компилятор от Microsoft для функций x86 теперь автоматом добавляет префикс в виде подчёркивания.Извини за назойливость - точно не скомпилирует?
точно не скомпилирует?скомпилировать-то он скомпилирует, но во время выполнения обязательно возникнет ошибка:
Исключение типа "System.EntryPointNotFoundException" возникло в dimas_help_sample.dll, но не было обработано в коде пользователя
Additional information: Unable to find an entry point named 'acedSetFunHelp' in DLL 'accore.dll'.
Похоже, что в этом случае используется какая-то другая функция, отличная от той, что применяется в случае пользовательских команд.Я тоже об этом думал...
Пользовательская справка открывается, но в обоих случаях текущим является первый раздел AboutТам у тебя два сомнительных момента - во первых топик по другому называется (пробела нет), во вторых в одной сессии не факт что на одну команду можно переназначать, НО это все лирика - по ходу мой косяк - я копипастил название из твого chm (для вставки в команду) и видимо просто не закрыл его - то есть он "повторно" открылся на старом месте - сейчас проверил - да всегда About - в общем надо "порыть" еще.
во первых топик по другому называется (пробела нет)Ну так я как раз и не использую пробел, как и нужно.
во вторых в одной сессии не факт что на одну команду можно переназначать,Когда я тестировал твой код, то для каждого из обозначенных мною вариантов перезапускал AutoCAD (для чистоты эксперимента).
и видимо просто не закрыл его - то есть он "повторно" открылся на старом местеэтой части фразы я не понял (очередные "точки\запятые" видимо).
Не понятно, почему тогда работает F1 для родных команд AutoCAD... Похоже, что в этом случае используется какая-то другая функция, отличная от той, что применяется в случае пользовательских команд. Это, мягко говоря, было бы очень странно...Ну почему же другая функция? Скорее всего таже самая. Но только для стандартных команд AutoCAD в его справке есть соответствующие разделы для команд.
Но только для стандартных команд AutoCAD в его справке есть соответствующие разделы для команд.В качестве значений параметров важны имя CHM файла и идентификатор (в виде строки) нужного раздела. Оба указаны в моём коде. А вы что подразумеваете под "разделами", если не это?
В качестве значений параметров важны имя CHM файла и идентификатор (в виде строки) нужного раздела. Оба указаны в моём коде. А вы что подразумеваете под "разделами", если не это?Вот такое впечатление, что у тебя AutoCAD игнорирует имя файла при вызове справке.
Вот такое впечатление, что у тебя AutoCAD игнорирует имя файла при вызове справкено ведь функции возвращали 5100, сообщая тем самым, что "всё пучком"... Вы уже отправили вопрос в ADN?
но ведь функции возвращали 5100, сообщая тем самым, что "всё пучком"...Читаем документацию по функции acedSetFunHelp:
acedSetFunHelp() returns RTNORM if it is successful. If pszFunctionName does not start with C:, it returns RTERROR. No checking of the acedHelp() parameters (pszHelpfile, pszTopic, and iCmd) is done until the Help call is actually made.Т.е. наличие файла и раздела для справки эта функция не проверяет. С другой стороны явный баг в документации по поводу требования C: Это требование действительно есть, но в lisp-функции (SetFunHelp ...), но не в функции acedSetFunHelp
The acedHelp() function returns RTNORM if it is successful. It returns RTERROR if the Help file is not found. Your application does not have to generate error messages because HTML Help reports errors directly to the user.Значит help-файл находится. Другой вопрос какой именно...
Другой вопрос какой именно...а какие тут могут быть варианты? Конкретный CHM файл ведь чётко прописан (абсолютный путь).
В 2009 x86 работает.Интересно.
В 2015 x86 лезет в интернет.Подчеркивание перед именем функции ставил? Кстати разница между твоей командой и командой Димы:
Подчеркивание перед именем функции ставил?Ну конечно же ставил. Если бы не ставил, то получил бы исключение в процессе выполнения кода.
Если бы не ставил, то получил бы исключение в процессе выполнения кода.Не обязательно. Я обратил внимание, на то, что ряд функций имеет дублированное имя (и с подчеркиванием и без).
Давай пробывать бредятинуНе надо. Я обратил внимание на то, что твой код работает в 2009-м, хотя почти ничем не отличается от моего, за исключением флага: Modal вместо Session. Я в ходе экспериментов менял флаг, однако делал это то ли в 2013-м, то ли в 2015-м.
Пока проверил в AutoCAD 2013 x86 в Windows XP SP3 и AutoCAD 2013 x64 Windows 7 - всё работает. Повторить ошибку не смог.
Справка открылась в соответствующих разделах все 3 раза.
AutoCAD 2014 x64 , Win7 x64
ACAD 2010 Win7*32 - как и у автора - ThroughProcess - вызывает нужную справку, в остальных случаях по F1 - выскакивает автокадная.
Проверил еще в x64 AutoCAD 2012, 2013, 2014 - всё нормально
Проверил на всякий случай в x86 AutoCAD 2008, но в Win7 X64 - работает только последний вариант. При этом в этом же AutoCAD'е но в Windows XP x86 работает нормально.
Acad 2014*64, Win8.1:
сборка и файл помощи на рабочем столе:
сборка загруженна успешно, регистрация выполненна
THROUGHATTRIBUTE - автокад ругается что такого файла нету, после загружает свою справку
THROUGHACEDSETFUNHELP - открывает "правильную" справку - курсор на пункте about (в 2010 был на "своем" месте)
THROUGHPROCESS - открывает "правильную" справку - курсор на пункте about
сборка на рабочем столе, файл справки в папке автокада:
сборка загруженна успешно, файл справки не найден
THROUGHATTRIBUTE - открывает "правильную" справку - курсор на пункте about
THROUGHACEDSETFUNHELP - автокад "молча" загружает свою справку
THROUGHPROCESS - ругается что не удается открыть справку
и т.д.
Собрался с духом и отправил запрос в ADN DevHelp.No comments...
они проверили в AutoCAD 2015 x86 и x64 и не выявили ошибкуБраво! Значит проблемы не существует.
Уточняйте версию и разрядность AutoCAD, для которых хотите проверить.Как обычно желательно последнюю. В крайнем случае из трех последних.