OLE. 1C
От: -=Al=- founderal.narod.ru
Дата: 23.08.02 06:46
Оценка:
нехочет инициализироваться ОЛЕ объект 1С:предприятия...

Пример с MSDEV.application работает исправно, но для V77.application не хочет правильно реагировать на QueryInterface.
CLSID взят из реестра.
Al
Re: OLE. 1C
От: alexzapl  
Дата: 23.08.02 07:04
Оценка:
Здравствуйте -=Al=-, Вы писали:

=>нехочет инициализироваться ОЛЕ объект 1С:предприятия...

=>Пример с MSDEV.application работает исправно, но для V77.application не хочет правильно реагировать на QueryInterface.
=>CLSID взят из реестра.


напиши кусок кода как ты его создаешь.
Re: OLE. 1C
От: Awaken Украина  
Дата: 23.08.02 08:00
Оценка:
Здравствуйте -=Al=-, Вы писали:

=>нехочет инициализироваться ОЛЕ объект 1С:предприятия...

извиняюсь не ту кнопку при ответе нажал

ты v77.application запускаешь из своей программы?
или наоборот из 1С свой COM-объект?
COM-объект для 1C должен реализовывать IDispatch. подробно это было в книжечке ихней описано ("Технология создания внешних компонент")
Re: OLE. 1C
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.08.02 21:54
Оценка:
Здравствуйте -=Al=-, Вы писали:

=>Пример с MSDEV.application работает исправно, но для V77.application не хочет правильно реагировать на QueryInterface.
=>CLSID взят из реестра.

Дело в том что в 1C про CLSID незнают. Они все черз диспач ганяют.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: OLE. 1C
От: -=Al=- founderal.narod.ru
Дата: 28.08.02 04:42
Оценка:
Здравствуйте alexzapl, Вы писали:

=>>Пример с MSDEV.application работает исправно, но для V77.application не хочет правильно реагировать на QueryInterface.
=>>CLSID взят из реестра.
A>напиши кусок кода как ты его создаешь.
Вот:
HRESULT hr;
const wchar_t *V77=L"V77.Application";
const unsigned int FuncNum(5);
wchar_t *FuncNames[FuncNum]={L"Initialize",L"EvalExpr",L"CreateObject", L"ExecuteBatch",L"RMTrade"};
CLSID id1C;
hr = CLSIDFromProgID(V77, &id1C);
IUnknown *punk=NULL;
hr = CoCreateInstance(id1C, NULL, CLSCTX_ALL | CLSCTX_REMOTE_SERVER, IID_IUnknown, (void**)&punk);
hr = OleRun(punk);

IDispatch *pdisp=NULL;
punk->QueryInterface(IID_IDispatch, (void**)&pdisp);
punk->Release();

LPCSTR name="RMTrade";
DISPID id_rmtrade=0;
hr=pdisp->GetIDsOfNames(IID_NULL, (WORD**)&name, 1, LOCALE_SYSTEM_DEFAULT, &id_rmtrade);
Al
Re[2]: OLE. 1C
От: -=Al=- founderal.narod.ru
Дата: 28.08.02 04:44
Оценка:
Здравствуйте Awaken, Вы писали:

A>Здравствуйте -=Al=-, Вы писали:

=>>нехочет инициализироваться ОЛЕ объект 1С:предприятия...
A>извиняюсь не ту кнопку при ответе нажал
?!?

A>ты v77.application запускаешь из своей программы?

Да.

A>или наоборот из 1С свой COM-объект?

Из 1С не надо. Требуетсяиспользовать возможности 1С:предприятия в своих целях.

A>COM-объект для 1C должен реализовывать IDispatch. подробно это было в книжечке ихней описано ("Технология создания внешних компонент")

Поцетировать можешь? чуть-чуть...
Al
Re[3]: OLE. 1C
От: Awaken Украина  
Дата: 28.08.02 06:05
Оценка:
A>>COM-объект для 1C должен реализовывать IDispatch. подробно это было в книжечке >ихней описано ("Технология создания внешних компонент")
=> Поцетировать можешь? чуть-чуть...

ой я так давно этим не занимаюсь ибо в штатах сижу 2 года как.
зайди на форум 1С-Профессионал , там народ ее на ftp выкладывал.

http://1c.hippo.ru/discuss/2b_frame.html
Re[3]: OLE. 1C
От: alexzapl  
Дата: 28.08.02 08:50
Оценка:
Здравствуйте -=Al=-, Вы писали:

=>Здравствуйте alexzapl, Вы писали:

=>>>Пример с MSDEV.application работает исправно, но для V77.application не хочет правильно реагировать на QueryInterface.
=>>>CLSID взят из реестра.
A>>напиши кусок кода как ты его создаешь.
=>Вот:
=> HRESULT hr;
=> const wchar_t *V77=L"V77.Application";
=> const unsigned int FuncNum(5);
=> wchar_t *FuncNames[FuncNum]={L"Initialize",L"EvalExpr",L"CreateObject", L"ExecuteBatch",L"RMTrade"};
=> CLSID id1C;
=> hr = CLSIDFromProgID(V77, &id1C);
=> IUnknown *punk=NULL;
=> hr = CoCreateInstance(id1C, NULL, CLSCTX_ALL | CLSCTX_REMOTE_SERVER, IID_IUnknown, (void**)&punk);
=> hr = OleRun(punk);

=> IDispatch *pdisp=NULL;
=> punk->QueryInterface(IID_IDispatch, (void**)&pdisp);
=> punk->Release();

=> LPCSTR name="RMTrade";
=> DISPID id_rmtrade=0;
=> hr=pdisp->GetIDsOfNames(IID_NULL, (WORD**)&name, 1, LOCALE_SYSTEM_DEFAULT, &id_rmtrade);

попробуй так:



      IDispatch *pdisp=NULL;
      hr = CoCreateInstance(id1C, NULL, CLSCTX_LOCAL_SERVER,IID_IDispatch, (void**)&pdisp);
      CComBSTR name="RMTrade";
      DISPID id_rmtrade=0;
      hr=pdisp->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &id_rmtrade);




Re[4]: OLE. 1C
От: -=Al=- founderal.narod.ru
Дата: 29.08.02 06:44
Оценка:
A>

A>      IDispatch *pdisp=NULL;
A>      hr = CoCreateInstance(id1C, NULL, CLSCTX_LOCAL_SERVER,IID_IDispatch, (void**)&pdisp);
A>      CComBSTR name="RMTrade";
A>      DISPID id_rmtrade=0;
A>      hr=pdisp->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &id_rmtrade);

A>

Спасибо, заработало. Кроме того я забыл вставить OleInitalization, но это мелочь (: А кто то ещё говорил, что бейсик-строка здесь непричём... помошничики.

A> ;)

А можно немного рассказать как в Invoke передавать параметры, вызываемой в её теле функции. Быду очень признателен. Это главным образом относится к:
V77.Initialization(V77.RMTrade, ...); Нужно запустить эту конструкцию в MSVC.
Al
Re[5]: OLE. 1C
От: alexzapl  
Дата: 29.08.02 07:00
Оценка:
Здравствуйте -=Al=-, Вы писали:


A>>

A>>      IDispatch *pdisp=NULL;
A>>      hr = CoCreateInstance(id1C, NULL, CLSCTX_LOCAL_SERVER,IID_IDispatch, (void**)&pdisp);
A>>      CComBSTR name="RMTrade";
A>>      DISPID id_rmtrade=0;
A>>      hr=pdisp->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &id_rmtrade);

A>>

=> Спасибо, заработало. Кроме того я забыл вставить OleInitalization, но это мелочь (: А кто то ещё говорил, что бейсик-строка здесь непричём... помошничики.

A>>

=> А можно немного рассказать как в Invoke передавать параметры, вызываемой в её теле функции. Быду очень признателен. Это главным образом относится к:
=> V77.Initialization(V77.RMTrade, ...); Нужно запустить эту конструкцию в MSVC.



небольшой пример как запустить 1С



static const CLSID clsV77App={0x63112D80,0x94F0,0x11D2,{0x9F,0x39,0x00,0x80,0x48,0xDA,0x12,0x0F}};

COleDispatchDriver m_drvApp;
m_drvApp.m_bAutoRelease=TRUE;
HRESULT hr=CoCreateInstance(clsV77App,NULL,CLSCTX_LOCAL_SERVER,IID_IDispatch,(void**)&(m_drvApp.m_lpDispatch));

CComBSTR name;

DISPID idTrade;
name="RMTrade";
hr=m_drvApp->m_lpDispatch->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&idTrade);

long m_RMTrade;
m_drvApp.GetProperty(idTrade,VT_I4,&m_RMTrade);

DISPID idInitialize;
name="Initialize";
hr=m_drvApp->m_lpDispatch->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&idInitialize);

CString path=m_strDBPath;// "C:\\Program Files\\1Cv77\\DataBase\\firma\\"
CString empty="NO_SPLASH_SHOW";
BYTE* parms=(BYTE*)(VTS_I4 VTS_BSTR VTS_BSTR);
BOOL retInitialize=FALSE;
m_drvApp.InvokeHelper(idInitialize,DISPATCH_METHOD,VT_BOOL,&retInitialize,parms,m_RMTrade,(void*)(LPCTSTR)path,(void*)(LPCTSTR)empty);
if(!retInitialize)
{
    AfxMessageBox("Ошибка инициализации приложения V77",MB_ICONERROR);
    return FALSE;
}



Re[5]: OLE. 1C
От: Vi2 Удмуртия http://www.adem.ru
Дата: 29.08.02 07:34
Оценка:
Здравствуйте -=Al=-, Вы писали:

=> Спасибо, заработало. Кроме того я забыл вставить OleInitalization, но это мелочь (: А кто то ещё говорил, что бейсик-строка здесь непричём... помошничики.

Бейсик-строка здесь действительно непричём. А причём, так это строка с 2-мя байтами на символ, а не обычные С-шные строки!

      IDispatch *pdisp=NULL;
      hr = CoCreateInstance(id1C, NULL, CLSCTX_LOCAL_SERVER,IID_IDispatch, (void**)&pdisp);
      LPOLESTR name = OLESTR("RMTrade");
// или
//    LPOLESTR name = L"RMTrade";
      DISPID id_rmtrade=0;
      hr=pdisp->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &id_rmtrade);


=> А можно немного рассказать как в Invoke передавать параметры, вызываемой в её теле функции.

IDispatch::Invoke -> Calling a Method With No Arguments и далее
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: OLE. 1C
От: -=Al=- founderal.narod.ru
Дата: 30.08.02 03:04
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>Бейсик-строка здесь действительно непричём. А причём, так это строка с 2-мя байтами на символ, а не обычные С-шные строки!

Ну дк, ежу понятно, что это юникод. А всё-таки, что ести буква 'B' в названии CComBSTR? Кроме того Билли придумал использовать при взаимодействии с оле-объектами булевы типы совместимые с этим, т.н. "языком программирования"... аж противно. Всё это (и ещё кое-что) и создало такое впечатление.
Al
Re[6]: OLE. 1C
От: -=Al=- founderal.narod.ru
Дата: 09.09.02 05:38
Оценка:
A>static const CLSID clsV77App={0x63112D80,0x94F0,0x11D2,{0x9F,0x39,0x00,0x80,0x48,0xDA,0x12,0x0F}};

A>COleDispatchDriver m_drvApp;

A>m_drvApp.m_bAutoRelease=TRUE;
[...поскипано...]


Всё это здорово, но, если я не ошибаюсь COleDispatchDriver из MFC. Я их немного недолюбливаю. Здесь кто-то писал, что этот класс есть не только в составе MFC. Как его подключить?
Al
Re[6]: OLE. 1C
От: -=Al=- founderal.narod.ru
Дата: 09.09.02 06:05
Оценка:
Здравствуйте Vi2, Вы писали:

=>> А можно немного рассказать как в Invoke передавать параметры, вызываемой в её теле функции.

Vi2>IDispatch::Invoke -> Calling a Method With No Arguments и далее


Здесь так всё запутено (с DISPPARAMS). Есть русский вариант?
Al
Re[7]: OLE. 1C
От: Vi2 Удмуртия http://www.adem.ru
Дата: 09.09.02 09:18
Оценка:
Здравствуйте -=Al=-, Вы писали:

Al> Здесь так всё запутено (с DISPPARAMS). Есть русский вариант?


А оно везде запутано. Русский вариант был мне без надобности: в английской документации всё без искажения переводчиков (а для себя я — не в счёт). Так что не знаю, есть ли он вообще.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[7]: OLE. 1C
От: Ерусов Дмитрий  
Дата: 09.09.02 09:19
Оценка:

    DISPID            dispid;
    DISPPARAMS        dispparams = {0};
    VARIANTARG        vars[2] = {0}; // Передаются два параметра
    VARIANTARG        vRes;

    CLSIDFromProgID(_bstr_t("www.www"), &cls);

    HRESULT hr = CoCreateInstance(cls, NULL, CLSCTX_SERVER, IID_IUnknown, (LPVOID*)&pUnk);
        
    hr = pUnk->QueryInterface(IID_IDispatch, (LPVOID*)&pDisp);
        
    hr = pDisp->GetIDsOfNames(
            IID_NULL,
            &szInitObj,
            1,
            LOCALE_USER_DEFAULT,
            &dispid);
        
    memset(&vRes, 0, sizeof(vRes)) ; 
// Заполняем массив параметров
// !!!! последний параметр указывается первым элементом в массиве VARIANTARG
    vars[0].vt = VT_BSTR;
    vars[0].bstrVal = (BSTR)Param2;
    vars[1].vt = VT_BSTR;
    vars[1].bstrVal = (BSTR)Param1;

    dispparams.rgvarg = vars;
    dispparams.cNamedArgs = 0;
    dispparams.rgdispidNamedArgs = NULL;
    dispparams.cArgs = 2;

    hr = pDisp->Invoke(
        dispid,
        IID_NULL,
        LOCALE_SYSTEM_DEFAULT,
        DISPATCH_METHOD,
        &dispparams,
        &vRes,
        NULL,
        NULL);
Re[8]: OLE. 1C
От: -=Al=- founderal.narod.ru
Дата: 10.09.02 00:38
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>А оно везде запутано. Русский вариант был мне без надобности: в английской документации всё без искажения переводчиков (а для себя я — не в счёт). Так что не знаю, есть ли он вообще.

Ладно, пойдём другим путём:
Насколько я понял, в cArgs помещаем количество параметров, в rgvarg указатель на массив VARIANTов с описаниями для каждого из них (о VARIANT потом). А теперь самое интересное: cNamedArgs — это идентификаторы OLE-приложения, если я не ошибаюсь. Точнее их количество. Но вот что помещать в rgdispidNamedArgs? Может быть указатель на массив индексов rgvarg, где они сидят или их ID-шки?
Al
Re[9]: cNamedArgs и rgdispidNamedArgs
От: Vi2 Удмуртия http://www.adem.ru
Дата: 10.09.02 03:51
Оценка:
Здравствуйте -=Al=-, Вы писали:

Al>Насколько я понял, в cArgs помещаем количество параметров, в rgvarg указатель на массив VARIANTов с описаниями для каждого из них (о VARIANT потом).


Да, всё верно. Единственная тонкость здесь — реверсивный порядок аргументов в rgvarg по сравнению с положением их в описании функции.

Al>А теперь самое интересное: cNamedArgs — это идентификаторы OLE-приложения, если я не ошибаюсь. Точнее их количество.


cNamedArgs — это количество поименованных аргументов при вызове функции. На С/С++, как правило, он равен 0, за исключением вызова свойства put или putref, когда равен 1 и rgdispidNamedArgs = & { DISP_PROPERTYPUT }.

Al>Но вот что помещать в rgdispidNamedArgs? Может быть указатель на массив индексов rgvarg, где они сидят или их ID-шки?


А, соответственно, rgdispidNamedArgs — это DISPID-ы этих поименованных аргументов. пример одного см. выше. Их получают при вызове GetIDsOfNames, передавая с именем функции и имена поименованных аргументов. Напрмер, для примера ниже GetIDsOfNames( ... , & { "Func", "b" }, ... ).

Именованные аргументы всегда располагаются в начале массива rgvarg, т.е. позиционально соответствуют rgdispidNamedArgs. rgdispidNamedArgs[n] — это DISPID аргумента, а rgvarg[n] — его значение.

Пример: Func([in] long a, [in] long b, [in] long c, [in] long d ).

Вызываем Func(vara,varb,varc,vard): cArgs = 4 rgvarg = & { variant(long(vard)), variant(long(varc)), variant(long(varb)), variant(long(vara)) } cNamedArgs = 0 rgdispidNamedArgs = NULL

Вызываем Func(b:=varb,vara,varc,vard): cArgs = 4 rgvarg = & { variant(long(varb)), variant(long(vard)), variant(long(varc)), variant(long(vara)) } cNamedArgs = 1 rgdispidNamedArgs = & { dispid_of_b /*скорее всего 2*/ }.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[10]: cNamedArgs и rgdispidNamedArgs
От: -=Al=- founderal.narod.ru
Дата: 11.09.02 02:07
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>Пример: Func([in] long a, [in] long b, [in] long c, [in] long d ).

Vi2>Вызываем Func(vara,varb,varc,vard): cArgs = 4 rgvarg = & { variant(long(vard)), variant(long(varc)), variant(long(varb)), variant(long(vara)) } cNamedArgs = 0 rgdispidNamedArgs = NULL

Vi2>Вызываем Func(b:=varb,vara,varc,vard): cArgs = 4 rgvarg = & { variant(long(varb)), variant(long(vard)), variant(long(varc)), variant(long(vara)) } cNamedArgs = 1 rgdispidNamedArgs = & { dispid_of_b /*скорее всего 2*/ }.


Ещё я попробовал сделать на MFC, но почемуто не хочет нормально инициализироваться 1С. Само приложение запускается, а возврат получается нулевой, то есть:
    // параметры командной строки
    CString strPath="config /D\"C:\\Program Files\\1Cv77\\Bratsk\" /nAl /p";
    CString strEmpty="NO_SPLASH_SHOW";
    parms=(BYTE*)(VTS_I4 VTS_BSTR VTS_BSTR );
    drvApp.InvokeHelper(id_init,DISPATCH_METHOD,VT_BOOL,&init,parms,RMTrade,(void*)(LPCTSTR)strPath,(void*)(LPCTSTR)strEmpty);

Здесть после выполения init==0... вроде всё перепробовал ): И ещё, имеет ли значание в каком режиме запускается предприятие?
Естественно после всего этого геморроя CreateObject не выполняется.
Al
Re[11]: VTS_BSTR - это BSTR строка
От: Vi2 Удмуртия http://www.adem.ru
Дата: 11.09.02 11:36
Оценка:
Здравствуйте -=Al=-, Вы писали:

Al> Ещё я попробовал сделать на MFC, но почемуто не хочет нормально инициализироваться 1С. Само приложение запускается, а возврат получается нулевой, то есть:


Al>    // параметры командной строки
Al>    CString strPath="config /D\"C:\\Program Files\\1Cv77\\Bratsk\" /nAl /p";
Al>    CString strEmpty="NO_SPLASH_SHOW";
Al>    parms=(BYTE*)(VTS_I4 VTS_BSTR VTS_BSTR );
Al>    drvApp.InvokeHelper(id_init,DISPATCH_METHOD,VT_BOOL,&init,parms,RMTrade,
Al>        (void*)(LPCTSTR)strPath,(void*)(LPCTSTR)strEmpty);

Al> Здесть после выполения init==0... вроде всё перепробовал ): И ещё, имеет ли значание в каком режиме запускается предприятие?
Al> Естественно после всего этого геморроя CreateObject не выполняется.

Ну что тебе сказать? Я с 1С не работал, так что конкретно не знаю. Всякое может быть.

Однако, чисто с позиций СОМ, передавать (void*)(LPCTSTR)strPath вместо BSTR (тэг VTS_BSTR) — ошибочно. BSTR — это не LPCWSTR (2 байта на символ) и уж тем более не LPСSTR (1 байт на символ).

Используй вместо CString классы _bstr_t или CComBSTR или метод CString::AllocSysString с последующим освобождением возвращаемого указателя.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[12]: VTS_BSTR - это BSTR строка
От: -=Al=- founderal.narod.ru
Дата: 12.09.02 00:12
Оценка:
Здравствуйте Vi2, Вы писали:


Vi2>Однако, чисто с позиций СОМ, передавать (void*)(LPCTSTR)strPath вместо BSTR (тэг VTS_BSTR) — ошибочно. BSTR — это не LPCWSTR (2 байта на символ) и уж тем более не LPСSTR (1 байт на символ).


Vi2>Используй вместо CString классы _bstr_t или CComBSTR или метод CString::AllocSysString с последующим освобождением возвращаемого указателя.

Оно заработало. Нужен был режим конфигуратора и ещё один момент.
Al
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.