简体   繁体   English

与COM相关的代码有什么问题?

[英]what's wrong in my code related to COM?

  *****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; 我还使COMVisible = true;

and register the class using RegAsm.exe Test.dll/tlb:Test.tlb /codebase 并使用RegAsm.exe Test.dll / tlb:Test.tlb / codebase注册该类

and imported the tlb in one cpp file as #import c:...\\Test.tlb named_guids 并在一个cpp文件中将tlb导入为#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. 在任何情况下,这在我的机器上以及我的虚拟机中都可以正常工作。如果我给sql2005可以工作,而我给sql2008可以工作。 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... 在另一台机器上,它仅在进入第三块时才显示错误代码为0x80004002。如果它进入第一块和第二块也可以在其他机器上正常工作。在第三块中发生了什么我不理解plzzzzzzzz在这方面对我有帮助...

Sharptooth u can plzz go through this one ..... 锐齿你可以通过这个.....

When working with COM, your assemblies should be "Release Builds". 使用COM时,程序集应为“发布版本”。 Make sure that's the case before digging around any further. 在深入研究之前,请确保是这种情况。

The IDiscoverPtr constructor will throw an exception if it can't instantiate the COM object. 如果IDiscoverPtr构造函数无法实例化COM对象,则将引发异常。 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). 最可能的原因是该COM对象未在该计算机的注册表中注册(未对实现IDiscover的.NET程序集运行重排)。

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. 第一个将HRESULT转换为_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? 您能发回错误代码是什么吗?

I have seen the error 0x80004002 E_NOINTERFACE if you expose a property of type DateTime on the com visible type you are trying to call CreateInstance() on. 如果您在尝试调用CreateInstance()的com可见类型上公开DateTime类型的属性,我已经看到错误0x80004002 E_NOINTERFACE。 I've also noticed that you have to Rebuild the project that imports the tlb file instead of a Build if the tlb file changes for example. 我还注意到,例如,如果tlb文件发生更改,则必须重建导入tlb文件而不是Build的项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM