2009-07-22 5 views
1
*****BLOCK_1**** 

    if(strcmpi(appName.c_str(),MSSQL)==0 ||strcmpi(appName.c_str(),MSSQL2005)==0) 
{ 


     if (FAILED(CoCreateInstance (CLSID_SQLDMOServer, NULL, CLSCTX_INPROC_SERVER, 
    IID_ISQLDMOServer, (LPVOID*)&m_pSQLServer))) { 


    DMOAvailable=false; 
    IDiscoverPtr pICalc; 
    HRESULT hRes=CoCreateInstance(Test::CLSID_SqlClass, NULL, CLSCTX_INPROC_SERVER,Test::IID_IDiscover, reinterpret_cast<void**> (&pICalc)); 

    if(FAILED(hRes)) 

     { 
      cout << "CoCreateInstance Failed on CLSID_SQLDMOServer\n"; 

     return FALSE; 
    } 

***BLOCK_2*** 

if((strcmpi(appName.c_str(),MSSQL2008)==0 || strcmpi(appName.c_str(),MSSQL2005)==0) && DMOAvailable==false) 
{ 

    HRESULT hr=CoInitialize(NULL); 
    IDiscoverPtr pICalc(__uuidof(SqlClass)); 
    if(FAILED(CoCreateInstance(Test::CLSID_SqlClass, NULL, CLSCTX_INPROC_SERVER, 
     Test::IID_IDiscover, reinterpret_cast<void**> (&pICalc)))) 
    { 
     cout<<" Loading SQLSMO failed This is because of SMO not Available "<<endl; 
     return FALSE; 
    } 

} 

*****BLOCK_3 **** 

if((strcmpi(appName.c_str(),MSSQL2008)==0 && DMOAvailable==true)) 
{ 

    HRESULT hr= CoInitialize(NULL); 

    cout<<"\nIn Init SqlServer DMO-true and SQL2008"<<endl; 



    HRESULT hRes=CoCreateInstance(Test::CLSID_SqlClass, NULL, CLSCTX_INPROC_SERVER, 
    Test::IID_IDiscover, reinterpret_cast<void**> (&pICalc)); 
    if(FAILED(hRes)) 
    { 
     printf(" Loading SQLSMO failed This is because of SMO not Available 0x%X\n",hRes) 
     return FALSE; 
    } 
    else 
     cout<<success; 


} 

return TRUE; 
} 


I have prepared the Test.dll in c# and in that i have a an interface IDiscover and a  class SqlClass implementing that interface.I have Manually assigned the Guid like this 

[System.Runtime.InteropServices.Guid("D4660088-308E-49fb-AB1A-77224F3FF851")] 

public interface IDiscover 
{ 
    string getSqlInstances(string HostName); 

    string getDB(string SQLInstanceName); 

    string getDatabaseInfo(string SQLInstanceName, string DBName); 
}; 

namespace Test 

    { 

    [System.Runtime.InteropServices.Guid("46A951AC-C2D9-48e0-97BE-91F3C9E7B065")] 

    public class SqlClass:IDiscover 

    { 

    } 
} 

Ich mache auch COMVisible = wahr;Was ist falsch in meinem Code in Bezug auf COM?

und registrieren die Klasse mit RegAsm.exe Test.dll/tlb: Test.tlb/Code-Basis

und importiert den TLB in einer CPP-Datei als Import c: ... \ Test.tlb named_guids

Das funktioniert gut in meiner Maschine und auch in meiner virtuellen Maschine für jeden Fall. Wenn ich sql2005 gab es funktioniert und ich gab sql2008 es funktioniert. und in einer anderen Maschine zeigt es, dass Fehlercode wie 0x80004002 nur beim Eintritt in den dritten Block.Wenn es in den ersten Block und 2. Block geht es funktioniert auch in anderen Maschinen gut. Was passiert im dritten Block ich verstehe nicht plzzzzzzzz mir dabei helfen regard ...

Sharptooth u gehen durch diese eine plzz kann .....

+0

Wird eine Ausnahme ausgelöst? Oder einige COM-Anrufberichte Fehler? – EFraim

+0

Wenn ich die Anwendung den Moment debugging, als der Debugger auf __uuid (sqlclass) zeigte, öffnet es ein visuelles C++ - Debuggerfenster und zeigt eine nicht behandelte Ausnahme am Speicherort XXXXXXXXX - Cute – Cute

Antwort

0

Der IDiscoverPtr Konstruktor eine Exception aus, wenn es nicht das COM-Objekt instanziiert kann. Der wahrscheinlichste Grund ist, dass das COM-Objekt nicht in der Registrierung dieses Computers registriert ist (regasm wurde nicht für die .NET-Assembly ausgeführt, die IDiscover implementiert).

+0

regasm wurde nicht für die COM-Server-Assembly ausgeführt Was bedeutet ?? ? Das selbe läuft well in meiner Maschine.wenn ich die exe kopiert habe und das auf irgendjemand anderem ausgeführt habe, scheint es so ... – Cute

+0

Sie müssen die .NET Assembly kopieren, die das IDiscover auf dem anderen Rechner implementiert und es dort registriert . Sonst wie wird COM es instanziieren? – sharptooth

+0

Yup ich tat es.Ich kopiere die Dll in Theta-Maschine und registrieren Sie es mit RegAsm auch. – Cute

0

Diese beiden Aussagen:

IDiscoverPtr pICalc(__uuidof(SqlClass)); 

HRESULT hRes=CoCreateInstance(Test::CLSID_SqlClass, NULL, CLSCTX_INPROC_SERVER, Test::IID_IDiscover, reinterpret_cast<void**> (&pICalc)); 

tun genau das Gleiche, so dass Sie sie nacheinander nicht laufen müssen.

Der erste übersetzt das HRESULT in eine Ausnahme vom Typ _com_error. Ich würde versuchen, etwas wie:

IDiscoverPtr pDiscover; 
    HRESULT hr = pDiscover.CreateInstance(__uuidof(SqlClass)); 
    if (FAILED(hr)) 
    { 
    printf("SQL DMO is not avilable. Error code: 0x%X\n", hr); 
    } 

Könnten Sie zurück, was der Fehlercode ist?

+0

Hallo der Fehlercode ist: 0x80040154 – Cute

+0

Das heißt REGDB_E_CLASSNOTREG oder einfach "Klasse nicht registriert". Also ist SQLDMO nicht registriert, vielleicht ist SQL Server nicht korrekt auf dem Zielrechner installiert? Dies sollte jedoch ein erwartetes Problem sein. Wenn Sie also beim Erstellen von Objekten von der Verwendung des IDiscoverPtr-Konstruktors auf CreateInstance umschalten, löst Ihre App in diesem Fall keine Ausnahmen mehr aus. –

+0

Jetzt korrigiert und dieses Mal 0x80004002 kommt .... – Cute

1

Wenn Sie mit COM arbeiten, sollten Ihre Assemblies "Release Builds" sein. Stellen Sie sicher, dass dies der Fall ist, bevor Sie weiter suchen.

+0

Ich bin gerade auf dieses seltsame Problem gestoßen und habe alle meine Assemblys in der Release-Konfiguration neu erstellt. Das Problem wurde aus einem unbekannten Grund behoben. In meinem C++ - Consumer habe ich #ifdef _DEBUG #import ".. \ MyManagedCOM \ bin \ Debug \ MyManagedCOM.tlb" raw_interfaces_only #else #import ".. \ MyManagedCOM \ bin \ Release \ MyManagedCOM.tlb" raw_interfaces_only #endif. Ich bin mir also nicht sicher, was das Problem in der Debug-Konfiguration verursachen würde. Ich verwende reg-freie COM. Haben Sie weitere Details zu den Gründen? Vielen Dank. –

+0

Debug-Builds sind an Debug-Versionen von Microsoft-DLLs gebunden (z. B. msvcr100d.dll anstelle von msvcr100.dll - beachten Sie das "d"). Diese Debug-Versionen der DLLs sind normalerweise nicht auf Benutzersystemen vorhanden. –

+0

Danke Matt, das macht Sinn für die OP-Umgebung! :) –

0

Ich habe den Fehler 0x80004002 E_NOINTERFACE gesehen, wenn Sie eine Eigenschaft vom Typ DateTime auf dem sichtbaren COM-Typ angeben, den Sie versuchen, CreateInstance() aufzurufen. Ich habe auch bemerkt, dass Sie das Projekt neu erstellen müssen, das die tlb-Datei anstelle eines Builds importiert, wenn sich die tlb-Datei beispielsweise ändert.

Verwandte Themen