Имя: Пароль:
1C
1С v8
Qt + COM (ActiveX) = Властелин упрвления сервером 1С предприятия
, , ,
0 KUL
 
20.07.13
05:29
Доброго времени суток господа!
Хочется общаться с 1С сервером через COM, т.е. подключиться, посмотреть какие пользователи в базе, выбрать чего-нибудь, добавить пользователя, посмотреть текущие сеансы подключения к 1С серверу. В общем, хочется от определенных данных, например групп в AD, делать определенные действия в 1С.
Подскажите как это в Qt можно реализовать?

Например есть <s>чудесный, скриптовый язык</s> PowerShell, в нём можно релизовать следующее:
//подключаю ком объект
$connector = New-Object -ComObject “V82.ComConnector”
//подключаюсь к базе 1С
$connection = $connector.Connect(“Srvr=”“сервер1С”“;Ref=”“база”“;Usr=”“пользователь”“;Pwd=”“пароль”“;”)
//смотрим пользователей в базе
$users = Get-Property -comObj $connection -prName “ПользователиИнформационнойБазы”



Вроде разобрался как использовать COM соединение

   #include <QApplication>
   #include <QtCore/QObject>
   #include <ActiveQt/QAxObject>
   #include <iostream>
   #include <oleauto.h>
   #include <QDebug>
   
   int main(int argc, char *argv[])
   {
       HRESULT r = OleInitialize(0);
       if (r != S_OK && r != S_FALSE)
       {qWarning("Qt:&#65288;error %x&#65289;",(unsigned int)r);}
       QCoreApplication a(argc, argv);
       QAxObject ax("V82.COMConnector",0);
       qDebug()<<ax.dynamicCall("Connect(\"Srvr=\"172.0.0.100\";Ref=\"base1\";Usr=\"1C-Bot\";Pwd=\"56q\";\")");
   
   //Здесь не выполняется выборка, потому что верхнее соединение уже разорвано  
    QAxObject *query = ax.querySubObject("NewObject(QString)", ("ПользователиИнформационнойБазы"));
   }

Если посмотреть логи 1С сервера, то происходит успешная авторизация, но через 2 секунды происходит разрыв. Почему??? Ведь я объект не удаляю!!!

Так-же можно отписываться о идеях здесь http://www.cyberforum.ru/qt/thread925124.html или здесь http://qt-project.org/forums/viewthread/29235/
1 KRV
 
20.07.13
08:14
А чем, мон шер, Вас штатные возможности не прельщают? Нафуя городить велосипед с шестиугольными колесами? Или надо оправдать зарплату?
2 mselling_ru
 
20.07.13
08:14
экономия на лицензиях
3 jsmith82
 
20.07.13
08:16
вирус пишешь?
4 IOL
 
20.07.13
09:16
(3) ага с ГУИком :-)
5 KUL
 
20.07.13
11:18
Извиняюсь, господа, а от куда столько негатива и бреда? Какой вирус, какая зарплата, какой велосипед? Есть 1с, есть AD, связать группы пользователей AD + добавлять/удалять в 1с, может быть ещё какую-нибудь плюшку.
И причем вирус с гуи, если ни одного класса виджен и/или диалог не задейстовано?

зы Если по делу писать нечего, лучше не писать (или направить туда, где могут подсказать), а не бестолковофлудием заниматься.
6 KUL
 
20.07.13
11:20
mselling_ru
И кстати, соединение COM полноценно ест 1 ключ лицензии как положено.
7 DmitrO
 
20.07.13
11:36
Ошибка в том, что метод Connect именно ВОЗВРАЩАЕТ IDispatch* , через который и надо выполнять все дальнейшие действия с 1С.
V82.COMConnector это соединитель, а не соединение. Объект соединения возвращает его метод Connect.

В скрипте повершел правильно написано.
А вот с++ коде не так.
8 DmitrO
 
20.07.13
11:38
А закрывается оно потому, что возрвщенное Методом Connect значение уходит из области видимости, и вероятно смарт указатель релизится.
9 Fragster
 
модератор
20.07.13
12:57
а я ющу пример нативной ВК на QT, потому что самому разбираться лень
10 Fragster
 
модератор
20.07.13
12:57
ищу
12 KUL
 
20.07.13
14:06
DmitrO
Спасибо за разъяснение! Но, что это за тип возвращаемый такой  IDispatch* не могу понять.
Допустим можно сделать вызов и получить через методы querySubObject и dynamicCall данные QAxObject * и QVariant соответственно. Но блин про IDispatcher нет ни слова в типе возвращаемых данных http://qt-project.org/doc/qt-5.0/activeqt/qaxbase.html#querySubObject-2

Ладно, ОК. Создадим указатель на активикс объект с адресом на результат, который мы получим при вызове внутреннего метода 1С connect.

QAxObject * ax = new QAxObject("V82.COMConnector");
QAxObject * ac = ax->querySubObject("Connect(\"Srvr=\"172.0.0.100\";Ref=\"base1\";Usr=\"1C-Bot\";Pwd=\"56q\";\")");

Через 30 сек после запуска вывалится всё та же ошибка!

QAxBase: Error calling IDispatch member Connect: Exception thrown by server
            Code       : 16389
            Source     : V82.COMConnector.1
            Description: {????????????????????????(36)}: ???????????? : 1C-Qt-B
ot-vostok ?? ??? ?????? ? ??????????? ?????????????. ???????? ?????? ??? ???????
??? ???????????? ? ??????????.
{???????????.????????????????????????.??????(172)}: ?????? ??? ?????? ?????? ???
?????? (????????): ?????? ??? ?????????? ??????????? - '????????????': {????????
???.????_???????????.??????(186)}: ?????? ??? ????????? ???????? ???????? ??????
??? (?????????????????????????????????????): ??????? ????????? ?????????????????
???? ???????? ????????? ??????
            Help       :
        Connect to the exception(int,QString,QString,QString) signal to catch this exception

Почему? Я же результат объекту передал!
13 KUL
 
20.07.13
14:09
Главное на 1С сервере происходит коннект -> авторизация(успешная) и через 3 сек -> завершение. Т.е. всё логично, как будто разрушается область выполнения запроса connect в функции ax->querySubObject. Но блин, адрес то отдан, почему разрушается то?
14 МихаилМ
 
20.07.13
14:28
(13)
IDispatch базовый com интерфейс.
15 KUL
 
20.07.13
14:32
Блин, уважаемые, если знаете киньте примерчиком из десяточки строк. Я понимаю почти логику, почти понимаю что нужно. Но блин всё почти ...
16 arsik
 
гуру
20.07.13
14:36
А зочем Qt?
Товарищ все плюшки по общению с сервером приложения на AutoIt написал. Минимум знаний, минимум времени, максимум КПД
17 KUL
 
20.07.13
15:16
arsik
есть уже что-то подобное на PowerShell. Но время выполнения длинное и памяти ОЗУ ест много. Хочется бинарно, быстро и стандартно.
18 DmitrO
 
20.07.13
15:29
мне кажется либо так:
QAxObject * ac = ax->querySubObject("Connect(\"Srvr=172.0.0.100;Ref=base1;Usr=1C-Bot;Pwd=56q;\")");
либо так:
QAxObject * ac = ax->querySubObject("Connect(\"Srvr=\"\"172.0.0.100\"\";Ref=\"\"base1\"\";Usr=\"\"1C-Bot\"\";Pwd=\"\"56q\"\";\")");
либо так:
QAxObject * ac = ax->querySubObject("Connect(const QString&)", "Srvr=\"172.0.0.100\";Ref=\"base1\";Usr=\"1C-Bot\";Pwd=\"56q\";");
19 etc
 
20.07.13
15:51
(17) большую часть памяти съедает COM объект, а больше всего времени уходит на его создание. Разве нет?
20 etc
 
20.07.13
15:55
(19)+ точнее даже не на создание а на соединение с базой.
21 KUL
 
20.07.13
16:29
DmitrO
Я в 12 сообщении тоже самое попробовал, и всё равно та-же ошибка :(, что Error calling IDispatch member Connect: Exception thrown by server

etc
Большую часть съедает платформа .NET (больше стони мегабайт (в то и две)) на которой собственно этот PowerShell и работает. Ну и + задержки самого скриптового языка.
А на C++ com при старте в поток, пока грузится тем временем к базе LDAP коннект и выборка юзверей из AD.
22 etc
 
20.07.13
16:36
(21) тогда понятно. Хотя задержки скриптового языка не особо я думаю велики. А так если бы интерейс не нужен то можно было бы на простом vbscript реализовать. Тогда по памяти было бы не особо затратно. Но параллельности конечно там нет.
23 KUL
 
21.07.13
16:00
Уважаемые господа, больше идей как правильно прикрутить соединение Connect 1С к QAxObject нет?
24 KUL
 
23.07.13
10:55
Оказалось, что коннект я правильно делаю и соединение успешно, просто моего пользователя небыло в справочнике пользователей, поэтому и не пускал :)

Теперь вот голову ломаю, как правильно список пользователей выбрать ...

QAxObject * ax = new QAxObject("V82.COMConnector");
QAxObject * ac = ax->querySubObject("Connect(\"Srvr=172.0.0.100;Ref=jkh02;Usr=1C-Bot;Pwd=qaz;\")");
QAxObject * ab = ac->querySubObject("CreateObject(ПользователиИнформационнойБазы)");


Так не получается, говорит что нет такого метода :/. Может кто-нибудь подскажет, где можно описание этих волшебных методов посмотреть?
25 arsik
 
гуру
23.07.13
23:59
(17) сравнил, то же мне. автоайти и повершелл.
Автоайти - это по сути конструктор скриптов, никаких потерь на загрузку нетфраемворка нет. Можно гуи слепить там же.
26 KUL
 
24.07.13
02:14
Тут вопрос не в том как можно, можно хоть на питоне, хоть на вбс, хоть на повершеле (и еще десятки других скриптовых обработчиков / и систем с компиляцией в "типо" байткод).
Вопрос в том, как это на Qt сделать правильно. (фанат GNU, C++ и т.д.).

Например, насколько я понял для коннектов внутри базы есть метод NewObject() ?! (с 1с программированием совсем не работал). Тогда не понятно, почему не выходит сделать :(

QAxObject * ab = ac->querySubObject("NewObject",QString::fromLocal8Bit("ПользователиИнформационнойБазы"));
27 KUL
 
25.07.13
06:14
Сейчас уже вопрос наверно не кутистам, а к 1сникам.
Подскажите пожалуйста, как правильно выбрать всех пользователей из справочника?
Например, захожу в конфигуратор - открыть конфигурацию
Слева есть список объектов и всего всего, есть пункт Справочники - Пользователи
Как правильно сделать NewObject чтобы получить ссылку на этих пользователей?
[CPP]    QAxObject * ax = new QAxObject("V82.COMConnector");
    QAxObject * ac = ax->querySubObject("Connect(\"Srvr=\"172.0.0.100\";Ref=\"base1\";Usr=\"1C-Bot\";Pwd=\"56q\";\")");
    QAxObject * ab = ac->querySubObject("NewObject",QAxObject::tr("Справочники.Пользователи;"));[/CPP]

но в ответ ругается
[CPP]QAxBase: Error calling IDispatch member NewObject: Exception thrown by server
             Code       : 1001
             Source     : 1C:Enterprise 8.2.15.319
             Description: ??? ?? ????????? '???????????.????????????;'
             Help       :
         Connect to the exception(int,QString,QString,QString) signal to catch t
his exception[/CPP]
По коду 1001 я понял, что это отсутствие данного метода, собственно поэтому и ошибка Error calling IDispatch member NewObject что никакой указатель не вернулся.
Но если сделать
[CPP]QAxObject * ab = ac->querySubObject("NewObject",QAxObject::tr("Справочники;"));[/CPP]
То какая то другая ошибка будет (кодировку не могу победить, извините), не 1001, т.е. как бы существует Справочники, но что-то не то вызываю.

Вопрос - как правильно сделать соединитель на Справочники.Пользователи и потом через метод String выбрать всех пользователей?
зы И ещё, если кто знает, подскажите пожалуйста, где можно посмотреть подробные логи действий на 1С сервере, ведь ошибка которая мне вопросиками отдается, должна же она где то на сервере храниться?!
28 Cube
 
25.07.13
06:22
(5) Хм... А я наоборот - из 1С рулю составом группы домена... И ничё, всё работает.
См. тут: v8: Как из 1С добавить пользователя в группу домена
29 KUL
 
26.07.13
08:39
Пытаюсь сделать
QAxObject * ab = ac->querySubObject("NewObject(\"InfoBaseUsersManager\");");
Это как ab = ac.InfoBaseUsersManager по 1совски

Но блин получаю ошибку
QAxBase: Error calling IDispatch member NewObject: Bad parameter count

Т.е. как бы возвращается не указатель на менеджер пользователей, а что-то другое?
Делаю для того, чтобы потом GetUsers с объектом ab сделать.
30 sikuda
 
26.07.13
08:53
(0,9) Блок ActiveQt - входит только в платную версию Qt, вы честны и ее уже купили ~2000$? Сам в свое время тыкал, но отказался от этой идеи.

А вот если нативную компоненту сделали бы. Это бы был бы шаг вперед..
31 KUL
 
26.07.13
08:56
Почему это он платный? Скачал обычную сборку, установил, указал CONFIG   += qaxcontainer и динамически линкую. Вроде ничего не нарушил.
32 sikuda
 
26.07.13
09:21
Молодой человек(Стаж: 6 дней) Раньше так было.
Сейчас с Digia запутаней http://qt-project.org/legal.html
33 KUL
 
27.07.13
17:17
Да нет, что то вы черезчур утрируете закрытость къюта
http://www.digia.com/ru/What-we-do/Qt/Qt-licensing/
Главное статично не линковать, да и всё. (было бы много проблем с лицензированием, кеды, влк и т.д. уже бы от къюта отказались бы)

Вопрос лицензирования конечно очень интересен, но хотелось бы по участвовать в дискуссиях по коннекту к 1С через COM средствами къюта
34 KUL
 
29.07.13
09:13
Для заблудших душ и для поиска гугла, ссылки где ребята мало-мальски разжевали чайнику 1С как правильно делать:
http://devtrainingforum.v8.1c.ru/forum/thread.jsp?id=615219#615219
http://www.cyberforum.ru/1c/thread928446.html