PDA

Visualizza la versione completa : [c++]com


giuseppe500
20-11-2008, 16:09
ciao.
Devo acedere ad un server com , e per questo cerco di risalire al clsid:


CLSID clsid;
hr = CLSIDFromProgID(OLESTR("Sap2000.SapObject"), &clsid);

tralascio la connessione al server com
questo funzionava con la versione 11 dell activex exe.

adesso non piu' cosi , dato che ho disinstallato la versione 11 e installato la versione12.
Ho provato a guardare nel vs2003 com / ole viewer ,ma dove devo guardare?
Grazie.

ps.


ho letto questo:
http://www.aleax.it/TutWin32/r37.htm

che dice:
L'identificatore di interfaccia deve esserci noto, visto che su quella interfaccia dovremo poi chiamare dei metodi; ad esempio, per un'interfaccia IScriptControl, dovremo usare come identificatore la costante IID_IScriptControl che gi abbiamo visto.

Viceversa, l'identificatore di classe pu non interessarci; se, sulla macchina su cui gira il nostro programma, fosse istallata una qualche implementazione piu` aggiornata, e quindi presumibilmente "migliore", di questa interfaccia, la cosa non ci darebbe alcun fastidio; in altri termini, gli identificatori di interfaccia sono cruciali, quelli di classe (implementazione) sono secondari.

proprio quello che mi servirebbe , dato che l'interfaccia rimane la stessa , e vorrei mantenere lo stesso codice sorgente se l'applicazione cambia release

giuseppe500
20-11-2008, 16:39
questa l'intestazione del file activex exe:


// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: Sap2000.exe

[
uuid(CB8ACBCC-972A-4B7E-9298-714E74858332),
version(23.0),
helpstring("Sap2000v12"),
custom(50867B00-BB69-11D0-A8FF-00A0C9110059, 9782)

]
library Sap2000
{
// TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib("stdole2.tlb");
// TLib : SAPFire v1.0 Callback Type Library for SAP2000v12 : {8F722E3E-DAD4-4F11-BA6C-312F2977F69A}
importlib("CsiGo_c.dll");


puo' aiutare?

Inoltre,e molto importante: ho incluso nel mio progetto dei file .tlh che venivano generati dalla direttiva #import file.exe che ho rimpiazzato dll' include dei .tlh e .tli stessi generati in precedenza.
Da allora non ho piu' rigenerato questi files.

posto il codice completo:



CLSID clsid;
m_StressIterator = NULL;

IUnknown *punk;
hr = CLSIDFromString(L"{CB8ACBCC-972A-4B7E-9298-714E74858332}", &clsid);
hr =CoCreateInstance(clsid,NULL,CLSCTX_SERVER,IID_IUn known, (void **)&punk) ;
hr= punk->QueryInterface(__uuidof(Sap2000::_SapObject), (void**)&m_pSap);

ll'errore su questa riga:



hr =CoCreateInstance(clsid,NULL,CLSCTX_SERVER,IID_IUn known, (void **)&punk) ;

ed : hr 0x80040154 Interfaccia non registrata. HRESULT

giuseppe500
21-11-2008, 09:52
ho trovato il problema:



hr = CLSIDFromProgID(L"Sap2000.SapObject", &clsid); //ok
hr =CoCreateInstance(clsid,NULL,CLSCTX_SERVER,IID_IUn known, (void **)&punk) ; //ok
hr= punk->QueryInterface(__uuidof(Sap2000::_SapObject), (void**)&m_pSap); //error nointerface


Il problema che se ho differenti versioni dell'activex exe __uuidof(Sap2000::_SapObject) cambia!
Se uso la direttiva #import con il path dell'eseguibile mi si creano due file :un .tli and a .tlh.
Se tutte le volte ricreo questi file il programma non da errori If i create ma se uso ad es un include di questi file gia creati, o se compilo il progetto e cambio l'activex(ad es se stata rilasciata una nuova release per me ad es da 12.0.0 a 12.0.1)
questo:


hr= punk->QueryInterface(__uuidof(Sap2000::_SapObject), (void**)&m_pSap); //error nointerface

ritorna un errore di NOinterface
probabilmente l' _uuidof(riid) cambia?
come posso risolvere ad es per avere un interfaccia generica comune a tutte le versioni(non sono propriamente versioni , ma release)dato che ho guardato i file .tlh e .tli generati e sono pressoch uguali?

Stoicenko
21-11-2008, 10:33
Il punto che l'oggetto com deve essere registrato.. se cambi la versione e non la registri non trovi l'interfaccia..

giuseppe500
21-11-2008, 11:17
e come lo registro?

Stoicenko
21-11-2008, 11:35
regsvr32 nomeoggettocom

giuseppe500
21-11-2008, 11:41
ho provato ma purtroppo non cambia niente.
Ma possibile risalire all' id dell ' interfaccia dal registro?
perch ho visto che esiste una funzione che permette di ottenere l'id da una stringa.
Basterebbe guardare nel registro?

giuseppe500
21-11-2008, 11:45
ps.
Mi dice che sap2000 stato caricato ma che non trova un unto di ingresso.
Sap2000 n exe activex se mmi sono scordato di dirlo.

giuseppe500
21-11-2008, 15:21
ho utilizzato questo codice:


CString CpApp::query(IUnknown* pUnk )
{
//if ( pUnk != NULL && ( ERROR_SUCCESS == key.Open( HKEY_CLASSES_ROOT, _T("Interface") ) ) )
{
HRESULT hr;
CLSID clsid;
IID id;
IUnknown *punk;
hr = CLSIDFromProgID(L"Sap2000.SapObject", &clsid);
hr =CoCreateInstance(clsid,NULL,CLSCTX_SERVER,IID_IUn known, (void **)&punk) ;

CRegKey* key = new CRegKey();
key->Open( HKEY_CLASSES_ROOT, _T("Interface"));
TCHAR szKeyName[1024] = _T("");
for ( int i = 0; ERROR_SUCCESS == RegEnumKey( key->m_hKey, i, szKeyName, 1024 ); i++ )
{
USES_CONVERSION;

if ( SUCCEEDED( CLSIDFromProgID(L"Sap2000.SapObject",&clsid ) ) )
{
Sap2000::_SapObjectPtr spObject;
CString str=CString(szKeyName);
BSTR bstr = str.AllocSysString();
hr =IIDFromString(bstr,&id);

hr=punk->QueryInterface(id, (void**)&spObject);
if ( SUCCEEDED(hr))
{
//entra per varie interfacce tra cui ad es IID_IMarshal
if(id != IID_IUnknown && id != IID_IMarshal)
{
AfxMessageBox("find!!!!");
}
TCHAR szValue[1024] = _T("");
LONG ncbValue = 1024;
ERROR_SUCCESS == RegQueryValue( key->m_hKey,szKeyName, szValue, &ncbValue );

}
}

}
key->Close();
}

return "";
}



per trovare runtime se esiste l'interfaccia sul registro, e esiste propro un interfaccia IID_Sap2000,solo che non so come utilizzarla una volta saputo il nome !
grazie.

Stoicenko
21-11-2008, 15:28
ma non hai un .h o qualcosa del genere che esponga i metodi? Con solo il nome e un puntatore che non puoi castare ad interfaccia sap che ci fai?

Loading