2009-07-22 2 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/кодовая

и импортирован TLB в одном CPP файле как #import с: ... \ Test.tlb named_guids

Это прекрасно работает на моей машине, а также в моей виртуальной машине для любого случая. Если я дал sql2005, он работает, и я дал sql2008, он работает. и в какой-то другой машине он показывает, что код ошибки как 0x80004002 только при входе в 3-й блок. Если он входит в 1-й блок и 2-й блок, его рабочий тон в другой машине тоже. Что происходит в 3-м блоке, я не понимаю, что plzzzzzzzz помогает мне в этом что касается ...

Sharptooth и может PLZZ пройти через этот .....

+0

Вызывает ли это исключение? Или какой-то COM-вызов сообщает о сбое? – EFraim

+0

, когда я отлаживаю приложение в тот момент, когда отладчик указал на __uuid (sqlclass), он открывает визуальное окно C++ debugge и показывает, что необработанное исключение происходит в ячейке памяти XXXXXXXXX - Cute – Cute

ответ

0

конструктор IDiscoverPtr будет сгенерировано исключение, если он не может создать экземпляр объекта COM. Наиболее вероятная причина заключается в том, что объект COM не зарегистрирован в реестре этой машины (regasm не был запущен для сборки .NET, которая реализует идентификатор).

+0

regasm не запускался для сборки сервера COM. ? То же самое запускается в моей машине. Когда я копировал exe и запускал его на каком-то другом, это похоже на это ... – Cute

+0

Вам нужно скопировать сборку .NET, которая реализует идентификатор IDiscover на другой машине и зарегистрировать его там , В противном случае, как COM-экземпляр это? – sharptooth

+0

Yup я сделал это. Я копирую 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 ваши сборки должны быть «Release Builds». Удостоверьтесь, что это так, прежде чем копать дальше.

+0

Я только столкнулся с этой странной проблемой, и восстановление всех моих сборок в конфигурации Release исправило проблему по неизвестной причине. В моем потребителе C++ у меня есть #ifdef _DEBUG #import ".. \ MyManagedCOM \ bin \ Debug \ MyManagedCOM.tlb" raw_interfaces_only #else #import ".. \ MyManagedCOM \ bin \ Release \ MyManagedCOM.tlb" raw_interfaces_only #endif. Поэтому я не уверен, что может вызвать проблему в конфигурации Debug. Я использую reg-free COM. У вас есть какие-либо подробности по каким-либо причинам для этого? Спасибо. –

+0

Отладочные сборки обязаны отлаживать версии DLL Microsoft (например, msvcr100d.dll вместо msvcr100.dll - отметить «d»). Эти отладочные версии DLL обычно не присутствуют в пользовательских системах. –

+0

Спасибо Мэтту, что имеет смысл для окружающей среды OP! :) –

0

Я видел ошибку 0x80004002 E_NOINTERFACE, если вы выставляете свойство типа DateTime на вид com, который вы пытаетесь вызвать CreateInstance(). Я также заметил, что вам нужно перестроить проект, который импортирует файл tlb вместо Build, если файл tlb изменяется, например.

Смежные вопросы