Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« : 22-07-2011 10:59 » |
|
Может кто помнит, я задавал кучу вопросов, когда делал программу для удалённого администрирования. Так вот, поделка сия готова, и заказчик задал вопрос - как это чудо познакомить с одинэской, то есть чтобы программу можно было запустить из 1C-ного кода, а также управлять запущенной программой оттуда (управлять - максимум вызывать определённые функции).
Как это делается ? О_о
|
|
« Последнее редактирование: 28-07-2011 16:38 от Алексей1153++ »
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #1 : 22-07-2011 11:30 » |
|
1С умеет работать с OLE объектами. Ты можешь в своей программе сделать OLE (COM) интерфейс для управления?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #2 : 22-07-2011 16:13 » |
|
если подскажешь, как это делается, то смогу Добавлено через 1 день, 23 часа, 57 минут и 24 секунды:А правильно ли я понимаю, что в 1С основная проблема - трудности с вызовом WinAPI, и поэтому написание и использование DLL необходимо именно для того, что 1C умеет подгрузить DLL и вызывать из него функции ? То есть, по сути, DLL у меня должно быть тупо посредником между 1С и WinAPI , который будет передавать команды управляемой программе (через экспортируемые функции)?
|
|
« Последнее редактирование: 24-07-2011 16:10 от Алексей1153 »
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #3 : 25-07-2011 12:51 » |
|
В принципе уже есть "универсальный" посредник для вызова WinAPI - это DynamicWrapper, так что можно обойтись WinAPI. Но по стандарту 1С имеет свой формат интерфейсов, через которые ведет общение с программой. Причем поскольку с выходом 8.2 стало возможным работать через веб-клиент не только в среде Windows, то в 8.2 добавлена переработанная версия работы с внешними компонентами: Native API. На сайте 1С описание находится в закрытой области (точнее его можно загрузить со страницы загрузки платформы), но поиск дает возможность найти его в просторах интернета
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 25-07-2011 14:59 » |
|
Kivals, спасибо, вот мне нечто вроде того, что по первой ссылке, и надо, судя по всему сделать. Я сегодня телегу по COM читал, вроде понятно, как это сделать. Потом отпишусь, что вышло ) Добавлено через 1 день, 1 час, 35 минут и 11 секунд:Kivals, глянь, пожалуйста, мои метания вот тут ) https://forum.shelek.ru/index.php/topic,11352
|
|
« Последнее редактирование: 26-07-2011 16:34 от Алексей1153 »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 28-07-2011 07:22 » |
|
Kivals, я тут поразбирался с визардом в студии и, вроде, родил DLL с COM-объектом внутри. Но не могу понять, в чём его протестировать. А также - кто должен регистрировать компонент, или же вручную надо вызывать regsvr32 ? Можешь попробовать? DLL в аттаче, название компонента "MyLIBR.My1Component" , там сейчас единственный метод __show_dlg(VARIANT_BOOL show); должен показывать и скрывать диалог (проект тоже пристегну на всякий случай)
|
|
« Последнее редактирование: 28-07-2011 14:06 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
|
|
« Ответ #6 : 28-07-2011 11:20 » |
|
Да, в системе его регистрируют (и разрегистрируют) посредством regsrv32. Не важно, руками или посредством вызова из другой программы. Иначе COM не будет недоступен. Протестить COM-объект легче всего в VB - для него это родной дом. Dim o As Object
' Создание объекта Set o = CreateObject("MyLIBR.My1Component")
' Вызов метода Call o.__show_dig(True) ' Альтернативный способ вызова ' o.__show_dig True
' Удаление объекта Set o = Nothing
|
|
« Последнее редактирование: 28-07-2011 20:30 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Kivals
|
|
« Ответ #7 : 28-07-2011 12:48 » |
|
Из 1С: Ошибок не вызывает, но и ничего не делает. В атачах тестовые обработки для 1С
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 28-07-2011 13:56 » |
|
Ром, VB щас поищу. VB6 сойдёт же ? Слав, у меня нет 1C Добавлено через 44 минуты и 35 секунд:вспомнил, что в экселе есть VBA , сделал модуль - а выполняться он не желает, эксель пишет, что макросы не разрешено выполнять Кстати, VBA не разрешает начинать имена с подчёркивания. Переделал без подчёркивания - пошагово мой диалог не показывается, пока не разобрался, почему. а просто мессадж бокс выводит. Так что, всё ок, спасибо всем за помощь Буду сейчас добивать эту кухню Добавлено через 4 часа, 50 минут и 51 секунду:происходит вот что: не создаётся диалог. Имеется в виду - хендл его окна My1Component::My1Component() { m_pDlg=new CSomeDlg(0); BOOL b=m_pDlg->Create(IDD_DIALOG1,0);
CString txt; txt.Format( L"Create=%d\n\r" L"GetLastError=%d\n\r" L"HWND=0x%08X" ,b ,GetLastError() ,m_pDlg->m_hWnd );
MessageBox(0,txt,L"345",MB_SYSTEMMODAL); ShowDialod(0); } выводится Create=0 GetLastError=0 HWND=0 почему окно не создаётся ? Добавлено через 4 часа, 27 минут и 57 секунд:догадался, однако ) My1Component::My1Component() { m_pApp= new CWinApp; // <<<<<<<<< m_pApp->InitInstance(); // <<<<<<<<<
m_pDlg=new CSomeDlg(0); m_pDlg->Create(IDD_DIALOG1,0);
ShowDialod(0); }
My1Component::~My1Component() { delete m_pDlg; delete m_pApp; // <<<<<<<<< }
|
DLL.rar (85.02 Кб - загружено 952 раз.)
|
« Последнее редактирование: 28-07-2011 19:31 от Алексей1153 »
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #9 : 28-07-2011 16:29 » |
|
Слав, у меня нет 1C Я помню - это как пример кода, возможно - для твоего клиента Однако как размерчик dll сразу поменялся... Похоже студия даже не вкомпилила ресурсы в первый раз Добавлено через 9 минут и 27 секунд:Все Ок - в 1С 7.7 и 8.2 (толстый и тонкий клиенты) все работает
|
|
« Последнее редактирование: 28-07-2011 16:38 от Kivals »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 28-07-2011 16:39 » |
|
Kivals, насчёт размера - я теперь статически слинковал с библиотекой MFC. До этого пропустил этот момент (но на работоспособность в данном случая это не влияло) Добавлено через 52 секунды:Все Ок - в 1С 7.7 и 8.2 (толстый и тонкий клиенты) все работает
это хорошо )) Сейчас встраиваю полученные знания в проект ) Добавлено через 13 часов, 55 минут и 23 секунды:Зак пишет: но помнишь, да, что нужно, чтобы он сам себя регистировал в системе, а не через командную строку? вот могу только батник предложить. Или ещё как-то можно ? ))))
|
|
« Последнее редактирование: 29-07-2011 06:35 от Алексей1153 »
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #11 : 29-07-2011 11:55 » |
|
CreateProcess(NULL, L"regsvr32.exe /s MyComLib.dll", NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, si, pi);
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #12 : 29-07-2011 16:45 » |
|
zubr, не не, как в студии это сделать я знаю. А там, как выразился зак, сидят бабушки-пользователи 1С . По моему, тут только батник самое удобное
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #13 : 29-07-2011 17:03 » |
|
Алексей1153++, причем здесь студия? WinAPI для любой программной платформы одинаково, будь то VS C++, VBA, Delphi, BCB и т. п.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #14 : 29-07-2011 17:06 » |
|
речь про 1С вообще-то
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #15 : 29-07-2011 17:11 » |
|
пытаюсь протестировать COM класс, следующие методы slavedclient_ConnectToServe)(BSTR* ServerAddress, LONG TcpPort); slavedclient_GetID(LONG* ID); slavedclient_GetPassword(BSTR* Password, LONG max_chars_count_with_zero); пробую на VBA в экселе 2000. Вопросы – в комментариях Public Sub f1()
Dim o As Object
Set o = CreateObject("TMV1C_Component.SlavedClient")
'тут нужна юникодная строка, как объявить ? Dim str(10) As Byte str(0) = 48 + 0 str(1) = 48 + 1 Call o.slavedclient_ConnectToServer(str, 80)
'правильно ли ? (нужна юникодная строка, передаваться должен указатель на буфер) Dim LL As Long LL = 77 Call o.slavedclient_GetID(LL)
'тоже нужна юникодная строка Dim pass(100 * 2) As Byte Call o.slavedclient_GetPassword(pass, 100)
Set o = Nothing End Sub
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #16 : 29-07-2011 17:24 » |
|
речь про 1С вообще-то Ну так из 1С функции API можно вызывать.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 29-07-2011 18:11 » |
|
zubr, если речь про этот вроппер В принципе уже есть "универсальный" посредник для вызова WinAPI - это DynamicWrapperто он заказчику не подошёл почему то
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #18 : 30-07-2011 07:12 » |
|
Леш, строка задается не массивом байт, а типом String - с указанием длины или без. Dim str1 As String(80) Dim str2 As String Насчет юникодности пока ничего не могу сказать. Из того, что прочел, я вынес, что строки VBA юникодные, а проблема заключена в строковых константах и встроенных функциях типа MsgBox. http://teaandbiscuits.org.uk/drupal/node/77Указателей в VBA нет, но есть передача по ссылке. Данный момент указывается в прототипе импортируемой функции. Для COM, думаю (не уверен), ByRef автоматом указывается.
|
|
« Последнее редактирование: 30-07-2011 07:29 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #19 : 30-07-2011 11:01 » |
|
VBA ругается на Dim str1 As String(80) Добавлено через 19 минут и 5 секунд:попробовал вот так, но явно что-то не то
|
|
« Последнее редактирование: 02-08-2011 21:23 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #20 : 30-07-2011 13:38 » |
|
Не связано с предыдущим постом (но тот тоже пока ещё не решился), в общем, по какой я грабле прогулялся! Запишу, кому-то спасёт много времени и нервов Если в COM-ном проект добавить ссылку из другого, рабочего проекта, в частности на создаваемый MFC-шный стандартный файл "MyProjectApp.cpp" , а там объявлена глобальная переменная CMyProjectApp theApp, то при сборке DLL+COM: первый признак ерунды (click to show) в консоли вывода: 1>Компиляция... 1>CMyProjectApp.cpp 1>Компоновка... 1>Внедрение манифеста... 1>Осуществляется регистрация выхода...
на этом происходит затык - ждать можно до талого снега, либо нажать отмену компиляции. зависает конкретно regsvr32.exe (студия сразу пытается зарегить COM объект) - его видно в диспетчере. Такая же фигня происходит и при попытке зарегить уже созданную DLL из командной строки второй признак ерунды (click to show) если из того же VBA попытаться создать объект, то выхода из CreateObject уже не произойдёт - висим. Если для глобальной переменной поставить тип CWinApp вместо CMyProjectApp (для этого эксперимента придётся заремарить extern CMyProjectApp theApp из "MyProjectApp.h"), либо вовсе убрать эту переменную, то затыков не происходит Причину такого поведения я не выяснил В принципе, я избавился от ссылки в DLL на этот файл, но всё равно хотелось бы узнать, где сябака
|
|
« Последнее редактирование: 30-07-2011 13:46 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
|
|
« Ответ #21 : 30-07-2011 14:49 » |
|
Чей-то ты, Леш, мудришь...
При регистрации происходит запуск DLL и вызов некой функции в ней (см. MSDN). Соотв., срабатывают зависимости и прочее.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #22 : 30-07-2011 15:04 » |
|
Я в курсе - вызывается DllRegisterServer Но глобальная переменная то создаётся при этом тоже. Но это ладно, я без неё обошёлся. Тут вот чего ещё: с передачей строк разобрался - дело в том, что BSTR - это уже указатель на WCHAR. Ещё раз разыменовал - и всё стало нормально с передачей. А вот передать буфер для заполнения не получается str1 = String(100, 0) Call o.slavedclient_GetPassword( str1, 100) передаться то он передаётся, но при попытке изменить содержимое строки программа валится, а васик показывает окно
|
111.PNG (9.94 Кб - загружено 3696 раз.)
|
« Последнее редактирование: 02-08-2011 21:23 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
|
|
« Ответ #23 : 30-07-2011 15:12 » |
|
Попробуй Dim str1 As String(100)
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #24 : 30-07-2011 15:30 » |
|
VBA ругается на
Dim str1 As String(80)
я кое что уже обнаружил, проверяю щас Добавлено через 15 минут и 59 секунд:в общем, в IDL файле я неправильно указал свойства параметра [id(5), helpstring("метод slavedclient_GetPassword")] HRESULT slavedclient_GetPassword([in,out] BSTR* Password, [in] LONG max_buffer_length); вместо "[in,out]" у меня было "[out]"
|
|
« Последнее редактирование: 30-07-2011 15:46 от Алексей1153 »
|
Записан
|
|
|
|
RXL
|
|
« Ответ #25 : 30-07-2011 16:36 » |
|
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #26 : 30-07-2011 18:25 » |
|
RXL, ага, так тоже выделяется. Но я уже вот так делал а я тут 2 часа мозгового сексу отхватил - оказалось, что фаервол отличился. Ну не создавался сокет, и всё тут! Потом вдруг думаю - отрублю ка я фаер... Хоп - открылся сокет! Запускаю фаер, смотрю правила - екселька то у меня весь запрещённый Остался ещё один момент - при закрытии компонента эксель вылетает. Щас буду рыться Добавлено через 1 час, 2 минуты и 58 секунд:Охренеть. Я столько мучался без отладчика, а студия-то позволяет отлаживать DLL ! Совершенно случайно это сейчас открыл для себя Сразу увидел, где ошибка, а так бы ни в жисть. Осталось ещё придумать, как исправить )) Добавлено через 34 минуты и 1 секунду:усё, силы зла побеждены ) Одно только беспокоит - где-то два потока остаются висеть после закрытия объекта. Что очень странно. Проверил с MyLIBR.My1Component (тестовый проект из аттача вверху) - там всё ок, ничего не остаётся висеть Добавлено через 13 часов, 13 минут и 8 секунд:выяснил, что дело в CWinThread - я их первый раз применил для потоков ради эксперимента. Если делать выход из процедуры потока сразу (для теста), то счётчик потоков не увеличивается. Причину пока не понял и пока забил (частых перезапусков всё равно не будет). Подозреваю, что если использовать обычные АПИшные потоки, то всё будет ок , но переделывать сейчас не буду ))
|
|
« Последнее редактирование: 31-07-2011 09:15 от Алексей1153 »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #27 : 02-08-2011 10:30 » |
|
Если в COM-ном проект добавить ссылку из другого, рабочего проекта, в частности на создаваемый MFC-шный стандартный файл "MyProjectApp.cpp" , а там объявлена глобальная переменная CMyProjectApp theApp, то при сборке DLL+COM:
выдалась свободная минутка, поэкспериментировал . Выявлен более "глубокий" виновник затыкания (но дальше я пока не стал разбираться) Поскольку у меня MFC-проект, основанный на диалоге, то внутри InitInstance открывается модальный диалог, после закрывания которого происходит возврат 0 (завершение приложения) С тестовым кодом, где взят чистый CDialog, которому подсунут ресурс моего диалога, затыкания не происходит. После строки вывода "1>Осуществляется регистрация выхода..." появляется диалог-зомби, его закрываем, компиляция удачно завершается. А вот эта корявая надпись как раз выводится из-за того, что возвращается 0. Если вернуть 1, то надписи нет. Интересно, возможно ли как-то узнать, как "запустили приложение" - штатно, или только для регистрации DLL ?
|
1.PNG (32.5 Кб - загружено 3833 раз.)
|
« Последнее редактирование: 02-08-2011 21:23 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
|
|
« Ответ #28 : 02-08-2011 11:52 » |
|
Вызов DllRegisterServer разве не информативно?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #29 : 02-08-2011 17:47 » |
|
не понимаю вопроса
|
|
|
Записан
|
|
|
|
|