views:

208

answers:

4
  *****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

  {

  }
}

I also make COMVisible=true;

and register the class using RegAsm.exe Test.dll/tlb:Test.tlb /codebase

and imported the tlb in one cpp file as #import c:...\Test.tlb named_guids

This is working fine in my Machine And also in My virtual Machine for any case.if i gave sql2005 it works and i gave sql2008 it working. and in some other machine it shows that errror code as 0x80004002 only when entering into 3rd block.if it enters 1st block and 2nd block its working fine in other machine also.what happening in 3rd block i am not understanding plzzzzzzzz help me in this regard...

Sharptooth u can plzz go through this one .....

A: 

The IDiscoverPtr constructor will throw an exception if it can't instantiate the COM object. The most likely reason is that the COM object is not registered in the registry of that machine (regasm was not run for the .NET assembly that implements the IDiscover).

sharptooth
regasm was not run for the COM server assembly Means what???The same is runing wel in my machine.when i copied the exe and run that one on some other it seems like this...
Cute
You need to copy the .NET assembly that implements the IDiscover onto the other machine and register it there. Otherwise how will COM instantiate it?
sharptooth
Yup i did it.I copy the Dll into theta machine and register it using RegAsm also.
Cute
Then you need to put a breakpoint onto the IDiscoverPtr constructor line and when the debugger stops there press F11 ("step into") and see exactly what code fails and for what reason. If there's an HRESULT its value will help you identify the problem.
sharptooth
ERRROr CODE: 0x80004002 what it mean???
Cute
It means that the class instantiated doesn't implement IDiscover. That's strange. Is the .NET assembly copied unchanged?
sharptooth
Btw there's a Winerror.h file that lists all the most frequent HRESULTs.
sharptooth
@sharptooth: it could be that IDiscover is TLB marshalled, and there's no typelibrary registered for the assembly.It looks like Cute is trying to talk to SQLDMO, so just registering MSSQL assemblies willy-nilly seems dangerous. Better to try and repair the SQL Server installation if it's even installed.
Kim Gräsman
@Kim: Quite possible explanation. IMO it's a bad idea to desing the COM component in such a way that it fails to instantiate when some external resource lime SQL Server is unavailable.
sharptooth
@sharptooth: SQLDMO is part of SQL Server, so in this instance it makes sense :)
Kim Gräsman
@sharptooth and Kim GrasmanI am using SMO since smo is Managed code i am created a c# dll and consumes it from unmanaged code.
Cute
Why does your main app need to be native -- if you already have to deploy a managed DLL, why not make the main app managed as well?
Kim Gräsman
+1  A: 

These two statements:

IDiscoverPtr pICalc(__uuidof(SqlClass));

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

do exactly the same thing, so you don't need to run them in sequence.

The first one translates the HRESULT into an exception of type _com_error. I'd try something like:

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

Could you post back what the error code is?

Kim Gräsman
Hi the error code is:0x80040154
Cute
That translates into REGDB_E_CLASSNOTREG or simply "Class not registered". So SQLDMO is not registered, maybe SQL Server is not properly installed on the target machine? This should be an expected problem, though, so if you switch from using IDiscoverPtr's constructor to CreateInstance when creating objects, your app will no longer throw exceptions in that case.
Kim Gräsman
Now corrected and this time 0x80004002 coming....
Cute
You can download HRPlus (bottom of page) from http://www.winwonk.com/utils/. It translates HRESULTs into readable messages most of the time.0x80004002 is E_NOINTERFACE, i.e. the interface you requested is not supported by the object. What did you do to "correct" the previous problem.
Kim Gräsman
A: 

Is this question related?

EFraim
A: 

When working with COM, your assemblies should be "Release Builds". Make sure that's the case before digging around any further.

Matt Jacobsen