2009-07-22 22 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 

    { 

    } 
} 

私もCOMVisible = trueにします。COMに関連する私のコードで何が間違っていますか?

とRegAsm.exeをTest.dllの/ TLBを使用してクラスを登録します。Test.tlb /コードベース

との#import Cのような1つのcppファイルにTLBをインポート:... \ Test.tlb named_guids

これは私のマシンでも問題なく動作しています。そして、私の仮想マシンでも、どのケースでも動作しています。私はsql2005にそれを与え、私はsql2008を動作させました。 とそれ以外のマシンでは、3番目のブロックに入ると0x80004002というエラーコードが表示されます.1番目のブロックに入り、2番目のブロックは他のマシンでも正常に動作します.3番目のブロックで何が起こっているのですか? ...それはCOMオブジェクトをインスタンス化できない場合IDiscoverPtrコンストラクタが例外をスローします

+0

例外がスローされますか?または、いくつかのCOMコールが失敗を報告しますか? – EFraim

+0

デバッガが__uuid(sqlclass)をポイントした時点でVisual C++デバッグウィンドウが開き、メモリ位置XXXXXXXXXで未処理の例外が発生した瞬間にアプリケーションをデバッグすると - – Cute

答えて

0

uは、このいずれかを通過plzzでき

Sharptooth .....。最も可能性の高い理由は、COMオブジェクトがそのマシンのレジストリに登録されていないことです(regasmはIDiscoverを実装する.NETアセンブリに対して実行されませんでした)。

+0

COMサーバアセンブリに対してregasmが実行されませんでしたか? ? 同じものが私のマシンのruning welです.Exeをコピーして別のマシンで実行すると、このように見えます... – Cute

+0

IDiscoverを実装している.NETアセンブリを他のマシンにコピーしてそこに登録する必要があります。そうでなければ、COMはどのようにインスタンス化しますか? – sharptooth

+0

うん、やったよ.Dllをthetaマシンにコピーし、RegAsmを使って登録する。 – Cute

0

これら二つの文:あなたが順序でそれらを実行する必要はありませんので、

IDiscoverPtr pICalc(__uuidof(SqlClass)); 

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

は、まったく同じことを行います。

最初のものは、HRESULTをタイプ_com_errorの例外に変換します。私は次のようなものを試してみよう:

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

エラーコードの内容を投稿できますか?

+0

こんにちはエラーコード:0x80040154 – Cute

+0

これは、REGDB_E_CLASSNOTREGまたは単に "クラスが登録されていません"に変換されます。 SQLDMOが登録されていないため、SQL Serverがターゲットマシンに正しくインストールされていない可能性がありますか?ただし、オブジェクトを作成するときにIDiscoverPtrのコンストラクタを使用してCreateInstanceに切り替えると、この場合にアプリケーションで例外がスローされることはありません。 –

+0

今度は0x80004002になります。 – Cute

1

COMで作業する場合、アセンブリは「リリースビルド」である必要があります。それ以上に掘り下げる前に、そのようにしてください。

+0

私はちょうどこの奇妙な問題に遭遇し、リリース構成ですべての私のアセンブリを再構築することで、何らかの不明な理由で問題が解決されました。私のC++コンシューマーでは、#ifdef _DEBUG #import ".. \ MyManagedCOM \ bin \ Debug \ MyManagedCOM.tlb" raw_interfaces_only #else #import ".. \ MyManagedCOM \ bin \ Release \ MyManagedCOM.tlb" raw_interfaces_only #endifがあります。だから私はデバッグ設定で問題の原因となるか分からない。私はregフリーのCOMを使用しています。あなたはこれを行うための任意の理由についてさらに詳細を持っていますか?ありがとうございました。 –

+0

デバッグビルドは、Microsoftのdllのデバッグバージョンにバインドされています(msvcr100.dllではなくmsvcr100d.dll - "d"に注意してください)。これらのデバッグバージョンのdllは通常、ユーザーシステムには存在しません。 –

+0

ありがとうマット、それはOPの環境にとって理にかなっています! :) –

0

CreateInstance()を呼び出そうとしているCOM可視型にDateTime型のプロパティを公開すると、0x80004002 E_NOINTERFACEエラーが発生しました。私はまた、tlbファイルが変更された場合にBuildの代わりにtlbファイルをインポートするプロジェクトを再ビルドしなければならないことに気付きました。

関連する問題