Accueil > > > [C/WIN32/WMI]SAVOIR SI UNE CLASSE COM EST INSTALLÉE
[C/WIN32/WMI]SAVOIR SI UNE CLASSE COM EST INSTALLÉE
Information sur la source
Description
Pour répondre à la question d'un boulay (Pas sur CS). Il voulait savoir comment faire pour déterminer si une classe COM précise est présente ou non. Je poste car il y a quand même une ou deux lignes pas inintéressantes. La requête WMI avec parcourt d'énumération en pur C par exemple. WMI est particulièrement lent, mais propose quand même une quantité impressionnante d'informations sur l'OS, le PC... Ce source propose plus ou moins trois méthodes tournant autour du sujet. Le programme peut prendre en entrée un ProgId ou un CLSID. Un ProgId, ça ressemble à ça : InternetExplorer.Application Un CLSID à ça : {0002DF01-0000-0000-C000-000000000046} Les CLSID ont été mis en place pour être vraiment sur que deux entreprises ne décident pas de faire deux composants COM avec le même nom. Cela aurait provoquer des problèmes de conflit évidents... Les CLSID sont en effet théoriquement unique (Basés sur l'adresse MAC du PC, de la date et de l'heure...) Lorsque l'on veut consommer un composant COM, on peut passer par sont CLSID ou sont ProgId, au choix. Le CLSID étant donc plus sûr. Ensuite, trois méthodes de validation sont disponibles : 1) Recherche dans le registre, et vérification de l'existence du fichier. L'installation d'une classe COM se fait généralement par l'appel d'une fonction exportée par le fichier (.dll, .ocx...) contenant la classe. Cette fonction s'appelle DllRegisterServer (Et son pendant DllUnregisterServer). C'est tout simplement ce que fait l'utilitaire de registration de classe COM regsvr32, il appelle simplement DllRegisterServer. Le code de DllRegisterServer installe donc la (ou les) classe(s) COM contenue(s) dans le fichier .dll/.ocx... Elle va en fait mettre à jour la base de registre, principalement dans : HKEY_LOCAL_MACHINE\SOFTWARE\Classes (Equivalent de HKEY_CLASSES_ROOT, obsolète) Elle va y ajouter une clé du nom du ProgId de la classe. En sous clé de cette clé, elle va mettre une clé CLSID, qui contiendra comme valeur par défaut le CLSID de la classe. Et dans : HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID Elle ajoute une clé du nom du CLSID. Cette clé contient : une sous clé ProgID qui contient le ProgId comme valeur par défaut. généralement une sous clé InprocServer32 avec comme valeur par défaut le chemin complet vers le .ocx/.dll. si la classe COM est proposée par un .exe, alors c'est une sous clé LocalServer32 avec comme valeur par défaut le chemin complet vers le .exe. La première méthode consiste donc à aller voir dans le registre si tout cela est présent, et si le fichier .ocx/.dll/.exe existe bien. 2) Listage des classes COM via WMI : WMI permet de lister les classes COM installées. WMI propose en effet la classe Win32_ClassicCOMClass : http://msdn.microsoft.com/en-us/library/aa394086 (VS.85).aspx Il suffit de faire un select * sur cette classe pour récupérer un énumérateur sur toutes les classes COM disponible. On peut comparer les CLSID de ces classes COM avec celui que l'on cherche. 3) Tentative via CoCreateInstance : On peut tout bêtement essayer de faire un CoCreateInstance, et regarder si ça a marché ou non ! 4) Il y a sûrment pas mal des méthodes dérivées : Par exemple en passant par CoGetClassObject au lieu de CoCreateInstance. Ou encore en cherchant le ProgId directement dans WMI, sans le traduire en CLSID puis rechercher le CLSID dans WMI. ...
Source
- #include "checkexistence.h"
-
- /**
- * Trouve le nom du fichier dans la base de registre et vérifie son existance
- */
- BOOL __stdcall CheckFromRegistry(TCHAR *lpClsid, HWND hWnd)
- {
- TCHAR lpBuffer[512]; /* Tampon à usage divers */
- TCHAR lpFile[512]; /* Fichier contenant la classe */
- TCHAR lpErrorMsg[512]; /* Message d'erreur */
- HKEY hClsid; /* Handle sur la clé correspondant au CLSID */
- HKEY hServer32; /* Handle sur la clé du *Server32 */
- DWORD nBufferSize; /* Taille du tampon pour la récupération du CLSID */
- LONG nReturnedValue; /* Valeur renvoyée par les appels */
- BOOL bResult;
- int nI;
-
- bResult = FALSE;
-
- lstrcpy(lpBuffer, _T("SOFTWARE\\Classes\\CLSID\\"));
- lstrcat(lpBuffer, lpClsid);
-
- /* classes\CLSID\lpClsid */
- nReturnedValue = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- lpBuffer, 0, KEY_READ, &hClsid);
- if (nReturnedValue)
- {
- SetLastError(nReturnedValue);
- Sys_ShowLastError();
- lstrcpy(lpErrorMsg, _T("Cannot open key: \"HKEY_LOCAL_MACHINE\\"));
- lstrcat(lpErrorMsg, lpBuffer);
- lstrcat(lpErrorMsg, _T("\""));
- MessageBox(hWnd, lpErrorMsg, NULL, MB_OK | MB_ICONERROR);
- goto the_end;
- }
-
- /* InProcServer32 et LocalServer32 */
- if (RegOpenKeyEx(hClsid, _T("InProcServer32"), 0, KEY_READ, &hServer32))
- {
- if (RegOpenKeyEx(hClsid, _T("LocalServer32"), 0, KEY_READ, &hServer32))
- {
- lstrcpy(lpErrorMsg, _T("Cannot find sub key InProcServer32 or "));
- lstrcat(lpErrorMsg, _T("LocalServer32 for key: \"HKEY_LOCAL_MACHINE\\"));
- lstrcat(lpErrorMsg, lpBuffer);
- lstrcat(lpErrorMsg, _T("\""));
- MessageBox(hWnd, lpErrorMsg, NULL, MB_OK | MB_ICONERROR);
- goto close_clsid;
- }
- }
-
- /* Récupération du nom du fichier */
- nBufferSize = 512;
- nReturnedValue = RegQueryValueEx(hServer32, NULL, NULL, NULL,
- (BYTE*)lpBuffer, &nBufferSize);
- if (nReturnedValue)
- {
- lstrcpy(lpErrorMsg,
- _T("Cannot read default value of key:\"HKEY_LOCAL_MACHINE\\"));
- lstrcat(lpErrorMsg, lpBuffer);
- lstrcat(lpErrorMsg, _T(")"));
- MessageBox(hWnd, lpErrorMsg, NULL, MB_OK | MB_ICONERROR);
- goto close_server32;
- }
-
- /* On résoud les variables d'environnement */
- ExpandEnvironmentStrings(lpBuffer, lpFile, 512);
-
- /* On enlève les quotes */
- if (lpFile[0] == '\"')
- {
- lstrcpy(lpFile, lpFile + 1);
- nI = 0;
- while (lpFile[nI]) nI++;
- lpFile[nI - 1] = '\0';
- }
-
- /* Vérification de l'existance du fichier */
- if (! FileSys_FileExists(lpFile))
- {
- lstrcpy(lpErrorMsg, _T("File: \""));
- lstrcat(lpErrorMsg, lpFile);
- lstrcat(lpErrorMsg, _T("\" does not exist."));
- MessageBox(hWnd, lpErrorMsg, NULL, MB_OK | MB_ICONERROR);
- goto close_server32;
- }
-
- bResult = TRUE;
- close_server32:
- RegCloseKey(hServer32);
- close_clsid:
- RegCloseKey(hClsid);
- the_end:
- return bResult;
- }
-
- /**
- * Cherche dans une énumération renvoyée par WMI
- */
- BOOL __stdcall CheckWithWmi(TCHAR *lpClsid, HWND hWnd)
- {
- IWbemLocator *lpLocator; /* Pour se connecter et la récup les services */
- IWbemServices *lpServices; /* Accès aux services WMI */
- BSTR lpConnectionString; /* Chaîne de connexion à CMIV2 */
- IEnumWbemClassObject *lpEnum; /* Enumérateur sur les classes COM */
- BSTR lpWQL; /* Langage de la query : WMI Query Language */
- BSTR lpRequest; /* Requête de récupération des classes COM */
- HRESULT nReturnValue; /* Vérification du retour du next */
- IWbemClassObject *lpComClass; /* L'objet WMI correspondant à la calsse COM */
- DWORD nReturned; /* Nombre d'objets retournés par le Next */
- BOOL bContinue; /* Continuer l'énumération ? */
- VARIANT clsidVar; /* Variant récupérant le CLSID de la classe */
- TCHAR lpCurrentClsid[256]; /* Clsid courant dans l'énumération */
- BOOL bResult;
-
- bResult = FALSE;
-
- /* On récupère le locator */
- if (CoCreateInstance(&CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
- &IID_IWbemLocator, (void**)&lpLocator))
- {
- MessageBox(hWnd, _T("Error on CoCreateInstance of WbemLocator"),
- NULL, MB_OK | MB_ICONERROR);
- goto the_end;
- }
-
- /* On se connecte au PC local */
- lpConnectionString = SysAllocString(L"ROOT\\CIMV2");
- if (lpLocator->lpVtbl->ConnectServer(lpLocator, lpConnectionString, NULL,
- NULL, NULL, 0, NULL, NULL, &lpServices))
- {
- MessageBox(hWnd, _T("Error in ConnectServer"), NULL, MB_OK | MB_ICONERROR);
- goto free_connection_string;
- }
-
- /* Configuration de la sécurité du proxy */
- if (CoSetProxyBlanket((IUnknown*)lpServices, RPC_C_AUTHN_WINNT,
- RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL,
- RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE))
- {
- MessageBox(hWnd, _T("Error in CoSetProxyBlanket"), NULL,
- MB_OK | MB_ICONERROR);
- goto release_services;
- }
-
- /* Exécution de la requête pour récupérer un énumérateur sur les classes */
- lpWQL = SysAllocString(L"WQL");
- lpRequest = SysAllocString(L"SELECT * FROM Win32_ClassicCOMClass");
- if (lpServices->lpVtbl->ExecQuery(lpServices, lpWQL, lpRequest,
- WBEM_FLAG_FORWARD_ONLY |
- WBEM_FLAG_RETURN_IMMEDIATELY,
- NULL, &lpEnum))
- {
- MessageBox(hWnd, _T("Error during query execution"), NULL,
- MB_OK | MB_ICONERROR);
- goto free_request;
- }
-
- /* Parcourt des classes COM */
- bContinue = TRUE;
- do
- {
- nReturnValue = lpEnum->lpVtbl->Next(lpEnum, WBEM_INFINITE, 1,
- &lpComClass, &nReturned);
- switch (nReturnValue)
- {
- case WBEM_S_NO_ERROR:
- /* Récupération du CLSID comme propriété ComponentId dans un VARIANT */
- lpComClass->lpVtbl->Get(lpComClass, L"ComponentId", 0, &clsidVar,
- NULL, NULL);
-
- /* Passage en TCHAR* pour la comparaison */
- #ifndef UNICODE
- WideCharToMultiByte(CP_ACP, 0, clsidVar.bstrVal, -1, lpCurrentClsid,
- 256, NULL, NULL);
- #else
- lstrcpy(lpCurrentClsid, clsidVar.bstrVal);
- #endif
-
- /* Comparaison avec l'entrée utilisateur */
- if (! lstrcmp(lpCurrentClsid, lpClsid))
- {
- bResult = TRUE;
- bContinue = FALSE;
- }
-
- VariantClear(&clsidVar);
- lpComClass->lpVtbl->Release(lpComClass);
- break;
- case WBEM_S_FALSE:
- bContinue = FALSE;
- break;
- default:
- MessageBox(hWnd, _T("Error during enumeration"), NULL,
- MB_OK | MB_ICONERROR);
- goto free_enum;
- }
- } while (bContinue);
-
- if (! bResult)
- MessageBox(hWnd, _T("No class found with this CLSID"), NULL,
- MB_OK | MB_ICONERROR);
-
- free_enum:
- lpEnum->lpVtbl->Release(lpEnum);
- free_request:
- SysFreeString(lpRequest);
- SysFreeString(lpWQL);
- release_services:
- lpServices->lpVtbl->Release(lpServices);
- free_connection_string:
- SysFreeString(lpConnectionString);
- lpLocator->lpVtbl->Release(lpLocator);
- the_end:
- return bResult;
- }
-
- /**
- * Instancie l'objet COM et analyse une éventuelle erreur
- */
- BOOL __stdcall CheckWithCreation(TCHAR *lpClsid, HWND hWnd)
- {
- CLSID clsid; /* CLSID de la classe, sous forme numérique */
- HRESULT nReturnValue; /* Pour tester le retour de CoCreateInstance */
- IUnknown *lpUnknown; /* Pointeur sur l'interface IUnknown */
- BOOL bResult;
-
- bResult = FALSE;
-
- if (! GetClsidFromString(lpClsid, &clsid, hWnd)) goto the_end;
-
- nReturnValue = CoCreateInstance(&clsid, NULL,
- CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
- &IID_IUnknown,
- (void**)&lpUnknown);
-
- switch (nReturnValue)
- {
- case S_OK:
- lpUnknown->lpVtbl->Release(lpUnknown);
- bResult = TRUE;
- break;
- case REGDB_E_CLASSNOTREG:
- MessageBox(hWnd, _T("Registration error, or CLSTX unavailable"),
- NULL, MB_OK | MB_ICONERROR);
- break;
- case E_NOINTERFACE:
- MessageBox(hWnd, _T("This interface is not available"),
- NULL, MB_OK | MB_ICONERROR);
- break;
- default:
- MessageBox(hWnd, _T("Unknown error in CoCreateInstance"),
- NULL, MB_OK | MB_ICONERROR);
- break;
- }
-
- the_end:
- return bResult;
- }
-
- /**
- * Renvoie un CLSID à partir d'une chaîne représentant un CLSID
- */
- BOOL __stdcall GetClsidFromString(TCHAR* lpClsidStr, CLSID* lpClsid, HWND hWnd)
- {
- WCHAR lpClsidStrW[256]; /* lpClsidStr en unicode pour CLSIDFromString */
- HRESULT nReturnValue; /* Récupération du code de retour */
- BOOL bResult;
-
- bResult = FALSE;
-
- /* Passage en unicode si nécessaire */
- #ifndef UNICODE
- MultiByteToWideChar(CP_ACP, 0, lpClsidStr, -1, lpClsidStrW, 256);
- #else
- lstrcpy(lpClsidStrW, lpClsidStr);
- #endif
-
- /* Conversion */
- nReturnValue = CLSIDFromString(lpClsidStrW, lpClsid);
- switch (nReturnValue)
- {
- case CO_E_CLASSSTRING:
- MessageBox(hWnd, _T("CLSID improperly formatted"),
- NULL, MB_OK | MB_ICONERROR);
- break;
- case REGDB_E_CLASSNOTREG:
- MessageBox(hWnd, _T("Corresponding CLSID not found"),
- NULL, MB_OK | MB_ICONERROR);
- break;
- case REGDB_E_READREGDB:
- MessageBox(hWnd, _T("Cannot read registery"),
- NULL, MB_OK | MB_ICONERROR);
- break;
- case NOERROR:
- bResult = TRUE;
- break;
- default:
- MessageBox(hWnd, _T("Unknown error in CLSIDFromString"),
- NULL, MB_OK | MB_ICONERROR);
- }
-
- return bResult;
- }
#include "checkexistence.h"
/**
* Trouve le nom du fichier dans la base de registre et vérifie son existance
*/
BOOL __stdcall CheckFromRegistry(TCHAR *lpClsid, HWND hWnd)
{
TCHAR lpBuffer[512]; /* Tampon à usage divers */
TCHAR lpFile[512]; /* Fichier contenant la classe */
TCHAR lpErrorMsg[512]; /* Message d'erreur */
HKEY hClsid; /* Handle sur la clé correspondant au CLSID */
HKEY hServer32; /* Handle sur la clé du *Server32 */
DWORD nBufferSize; /* Taille du tampon pour la récupération du CLSID */
LONG nReturnedValue; /* Valeur renvoyée par les appels */
BOOL bResult;
int nI;
bResult = FALSE;
lstrcpy(lpBuffer, _T("SOFTWARE\\Classes\\CLSID\\"));
lstrcat(lpBuffer, lpClsid);
/* classes\CLSID\lpClsid */
nReturnedValue = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
lpBuffer, 0, KEY_READ, &hClsid);
if (nReturnedValue)
{
SetLastError(nReturnedValue);
Sys_ShowLastError();
lstrcpy(lpErrorMsg, _T("Cannot open key: \"HKEY_LOCAL_MACHINE\\"));
lstrcat(lpErrorMsg, lpBuffer);
lstrcat(lpErrorMsg, _T("\""));
MessageBox(hWnd, lpErrorMsg, NULL, MB_OK | MB_ICONERROR);
goto the_end;
}
/* InProcServer32 et LocalServer32 */
if (RegOpenKeyEx(hClsid, _T("InProcServer32"), 0, KEY_READ, &hServer32))
{
if (RegOpenKeyEx(hClsid, _T("LocalServer32"), 0, KEY_READ, &hServer32))
{
lstrcpy(lpErrorMsg, _T("Cannot find sub key InProcServer32 or "));
lstrcat(lpErrorMsg, _T("LocalServer32 for key: \"HKEY_LOCAL_MACHINE\\"));
lstrcat(lpErrorMsg, lpBuffer);
lstrcat(lpErrorMsg, _T("\""));
MessageBox(hWnd, lpErrorMsg, NULL, MB_OK | MB_ICONERROR);
goto close_clsid;
}
}
/* Récupération du nom du fichier */
nBufferSize = 512;
nReturnedValue = RegQueryValueEx(hServer32, NULL, NULL, NULL,
(BYTE*)lpBuffer, &nBufferSize);
if (nReturnedValue)
{
lstrcpy(lpErrorMsg,
_T("Cannot read default value of key:\"HKEY_LOCAL_MACHINE\\"));
lstrcat(lpErrorMsg, lpBuffer);
lstrcat(lpErrorMsg, _T(")"));
MessageBox(hWnd, lpErrorMsg, NULL, MB_OK | MB_ICONERROR);
goto close_server32;
}
/* On résoud les variables d'environnement */
ExpandEnvironmentStrings(lpBuffer, lpFile, 512);
/* On enlève les quotes */
if (lpFile[0] == '\"')
{
lstrcpy(lpFile, lpFile + 1);
nI = 0;
while (lpFile[nI]) nI++;
lpFile[nI - 1] = '\0';
}
/* Vérification de l'existance du fichier */
if (! FileSys_FileExists(lpFile))
{
lstrcpy(lpErrorMsg, _T("File: \""));
lstrcat(lpErrorMsg, lpFile);
lstrcat(lpErrorMsg, _T("\" does not exist."));
MessageBox(hWnd, lpErrorMsg, NULL, MB_OK | MB_ICONERROR);
goto close_server32;
}
bResult = TRUE;
close_server32:
RegCloseKey(hServer32);
close_clsid:
RegCloseKey(hClsid);
the_end:
return bResult;
}
/**
* Cherche dans une énumération renvoyée par WMI
*/
BOOL __stdcall CheckWithWmi(TCHAR *lpClsid, HWND hWnd)
{
IWbemLocator *lpLocator; /* Pour se connecter et la récup les services */
IWbemServices *lpServices; /* Accès aux services WMI */
BSTR lpConnectionString; /* Chaîne de connexion à CMIV2 */
IEnumWbemClassObject *lpEnum; /* Enumérateur sur les classes COM */
BSTR lpWQL; /* Langage de la query : WMI Query Language */
BSTR lpRequest; /* Requête de récupération des classes COM */
HRESULT nReturnValue; /* Vérification du retour du next */
IWbemClassObject *lpComClass; /* L'objet WMI correspondant à la calsse COM */
DWORD nReturned; /* Nombre d'objets retournés par le Next */
BOOL bContinue; /* Continuer l'énumération ? */
VARIANT clsidVar; /* Variant récupérant le CLSID de la classe */
TCHAR lpCurrentClsid[256]; /* Clsid courant dans l'énumération */
BOOL bResult;
bResult = FALSE;
/* On récupère le locator */
if (CoCreateInstance(&CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
&IID_IWbemLocator, (void**)&lpLocator))
{
MessageBox(hWnd, _T("Error on CoCreateInstance of WbemLocator"),
NULL, MB_OK | MB_ICONERROR);
goto the_end;
}
/* On se connecte au PC local */
lpConnectionString = SysAllocString(L"ROOT\\CIMV2");
if (lpLocator->lpVtbl->ConnectServer(lpLocator, lpConnectionString, NULL,
NULL, NULL, 0, NULL, NULL, &lpServices))
{
MessageBox(hWnd, _T("Error in ConnectServer"), NULL, MB_OK | MB_ICONERROR);
goto free_connection_string;
}
/* Configuration de la sécurité du proxy */
if (CoSetProxyBlanket((IUnknown*)lpServices, RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE))
{
MessageBox(hWnd, _T("Error in CoSetProxyBlanket"), NULL,
MB_OK | MB_ICONERROR);
goto release_services;
}
/* Exécution de la requête pour récupérer un énumérateur sur les classes */
lpWQL = SysAllocString(L"WQL");
lpRequest = SysAllocString(L"SELECT * FROM Win32_ClassicCOMClass");
if (lpServices->lpVtbl->ExecQuery(lpServices, lpWQL, lpRequest,
WBEM_FLAG_FORWARD_ONLY |
WBEM_FLAG_RETURN_IMMEDIATELY,
NULL, &lpEnum))
{
MessageBox(hWnd, _T("Error during query execution"), NULL,
MB_OK | MB_ICONERROR);
goto free_request;
}
/* Parcourt des classes COM */
bContinue = TRUE;
do
{
nReturnValue = lpEnum->lpVtbl->Next(lpEnum, WBEM_INFINITE, 1,
&lpComClass, &nReturned);
switch (nReturnValue)
{
case WBEM_S_NO_ERROR:
/* Récupération du CLSID comme propriété ComponentId dans un VARIANT */
lpComClass->lpVtbl->Get(lpComClass, L"ComponentId", 0, &clsidVar,
NULL, NULL);
/* Passage en TCHAR* pour la comparaison */
#ifndef UNICODE
WideCharToMultiByte(CP_ACP, 0, clsidVar.bstrVal, -1, lpCurrentClsid,
256, NULL, NULL);
#else
lstrcpy(lpCurrentClsid, clsidVar.bstrVal);
#endif
/* Comparaison avec l'entrée utilisateur */
if (! lstrcmp(lpCurrentClsid, lpClsid))
{
bResult = TRUE;
bContinue = FALSE;
}
VariantClear(&clsidVar);
lpComClass->lpVtbl->Release(lpComClass);
break;
case WBEM_S_FALSE:
bContinue = FALSE;
break;
default:
MessageBox(hWnd, _T("Error during enumeration"), NULL,
MB_OK | MB_ICONERROR);
goto free_enum;
}
} while (bContinue);
if (! bResult)
MessageBox(hWnd, _T("No class found with this CLSID"), NULL,
MB_OK | MB_ICONERROR);
free_enum:
lpEnum->lpVtbl->Release(lpEnum);
free_request:
SysFreeString(lpRequest);
SysFreeString(lpWQL);
release_services:
lpServices->lpVtbl->Release(lpServices);
free_connection_string:
SysFreeString(lpConnectionString);
lpLocator->lpVtbl->Release(lpLocator);
the_end:
return bResult;
}
/**
* Instancie l'objet COM et analyse une éventuelle erreur
*/
BOOL __stdcall CheckWithCreation(TCHAR *lpClsid, HWND hWnd)
{
CLSID clsid; /* CLSID de la classe, sous forme numérique */
HRESULT nReturnValue; /* Pour tester le retour de CoCreateInstance */
IUnknown *lpUnknown; /* Pointeur sur l'interface IUnknown */
BOOL bResult;
bResult = FALSE;
if (! GetClsidFromString(lpClsid, &clsid, hWnd)) goto the_end;
nReturnValue = CoCreateInstance(&clsid, NULL,
CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
&IID_IUnknown,
(void**)&lpUnknown);
switch (nReturnValue)
{
case S_OK:
lpUnknown->lpVtbl->Release(lpUnknown);
bResult = TRUE;
break;
case REGDB_E_CLASSNOTREG:
MessageBox(hWnd, _T("Registration error, or CLSTX unavailable"),
NULL, MB_OK | MB_ICONERROR);
break;
case E_NOINTERFACE:
MessageBox(hWnd, _T("This interface is not available"),
NULL, MB_OK | MB_ICONERROR);
break;
default:
MessageBox(hWnd, _T("Unknown error in CoCreateInstance"),
NULL, MB_OK | MB_ICONERROR);
break;
}
the_end:
return bResult;
}
/**
* Renvoie un CLSID à partir d'une chaîne représentant un CLSID
*/
BOOL __stdcall GetClsidFromString(TCHAR* lpClsidStr, CLSID* lpClsid, HWND hWnd)
{
WCHAR lpClsidStrW[256]; /* lpClsidStr en unicode pour CLSIDFromString */
HRESULT nReturnValue; /* Récupération du code de retour */
BOOL bResult;
bResult = FALSE;
/* Passage en unicode si nécessaire */
#ifndef UNICODE
MultiByteToWideChar(CP_ACP, 0, lpClsidStr, -1, lpClsidStrW, 256);
#else
lstrcpy(lpClsidStrW, lpClsidStr);
#endif
/* Conversion */
nReturnValue = CLSIDFromString(lpClsidStrW, lpClsid);
switch (nReturnValue)
{
case CO_E_CLASSSTRING:
MessageBox(hWnd, _T("CLSID improperly formatted"),
NULL, MB_OK | MB_ICONERROR);
break;
case REGDB_E_CLASSNOTREG:
MessageBox(hWnd, _T("Corresponding CLSID not found"),
NULL, MB_OK | MB_ICONERROR);
break;
case REGDB_E_READREGDB:
MessageBox(hWnd, _T("Cannot read registery"),
NULL, MB_OK | MB_ICONERROR);
break;
case NOERROR:
bResult = TRUE;
break;
default:
MessageBox(hWnd, _T("Unknown error in CLSIDFromString"),
NULL, MB_OK | MB_ICONERROR);
}
return bResult;
}
Conclusion
Appli C unicode ou non (Flag dans tools.h). Windows 2000 pro minimum (Voir XP minimum). Testée sous XP. Pas de CRT (Exécutable de 16Ko).
Réalisé sous VC6. Non compatible Code::Blocks/MinGW. En effet, pour WMI, il faut Wbemcli.h/Wbemidl.h, qui ne sont proposés avec MinGW. Ces headers ne sont apparemment pas non plus fournis avec VC6... Il faut récupérer le WMI SDK dans le platform SDK. Le dernier platform sdk supportant officiellement VC6 est récupérable ici : http://www.microsoft.com/msdownload/platformsdk/ sdkupdate/psdk-full.htm
Historique
- 19 mai 2009 17:31:28 :
- Ortho
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Entrée de registre pour composant activex [ par RaSa ]
Bonjour,Je recherche une spécification qui liste exhaustivement les entrées nécessaires (et possible) dans le registre pour l'inscripti
CLSID et ActiveX [ par bayby ]
Bonjour tous le monde,je debute dans la creation d'objet COM en VB.NET. cependant une fois mon objet créé je n'arrive pas à l'utiliser en tant que Act
Utiliser OLE COM dans une DLL [ par andrebernard ]
Bonjour à tousVoila, je suis un débutant de chez débutant, je veux dire par la que c'est la premeire fois que je lance visual C++ 6.C'est un vieux rev
Vérifier valeur registre [ par Sniperr ]
Bonsoir,J'aimerais savoir comment vérifier si (par exemple) la valeur "Version" existe dans "HKEY_LOCAL_MACHINE\SOFTWARE\AGORA Software BV\codevb".J'a
Cle de registre Reg_Binary [ par chinois0013 ]
Bonjour,J'ai un petit problème et j'ai grand besoin de votre aide !Je ne comprends pas comment sont coder les valeurs binaires des clés de registre.Co
DBGrid [ par lillith212 ]
Bonjour à toutes et à tous,Nouvelle dans la programmation en C++, je suis entrain de développer un logiciel qui communique via un port com et qui affi
bloquer www.ebuddy.com [ par johann1609 ]
bonjour,je voudrais savoir si quelqu'un pouvais me dire comment bloquer lesa sites comme ebuddy.com j'ai essayer de metre dans la liste de site interd
Dll MFC contenant activex [ par nicob42 ]
BonjourJe voudrais créer une dll MFC sous visual 2003 contenant un activex.Mon probleme : - Une fois la dll créer, je pose sur ma fenetre un activex e
Pb d'un driver Audio:pas de son!!! [ par cpp26 ]
salut;j'ai un notebook HP 2510p.Depuis quelques jours j'ai formaté mon ordi.En effet j'avais pas du probleme avec les drivers ;je les ai trouvés au s
Problème utilisation OLE DB [ par sanantonio99 ]
<link rel="File
|
Derniers Blogs
TECHDAYS PARIS 2010 : ADMINISTRATION SHAREPOINT 2010TECHDAYS PARIS 2010 : ADMINISTRATION SHAREPOINT 2010 par ROMELARD Fabrice
Animé par: Patrick Guimonet et Benoit Hamet Cette session traitera des différents points exigés durant les taches d'administration : Planification (architecture, hébergement, authentification, .) Opération e...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice [TECHDAYS 2010] #03 - WEB CONTENT MANAGEMENT SOUS SHAREPOINT 2010[TECHDAYS 2010] #03 - WEB CONTENT MANAGEMENT SOUS SHAREPOINT 2010 par pierre
Stephane Cordonnier de MCNext nous présente les fonctionnalités Web Content Management (WCM) sous SharePoint 2010. Qu'est-ce que le WCM ECM, GED, RM, WCM c'est quoi Plateforme SharePoint Versions SharePoint 2010 SharePoint Fondation...
Cliquez pour lire la suite de l'article par pierre [DESIGN PATTERNS] PARTIE 2: DIP: DEPENDENCY INVERSION PRINCIPLE[DESIGN PATTERNS] PARTIE 2: DIP: DEPENDENCY INVERSION PRINCIPLE par tja
C'est le dernier principe des principes du Design Orienté Objet (The Principles of Object Oriented Design) fondés par Robert C. Martin plus connu sous le pseudonyme d'Uncle Bob.
l'image empruntée de LosTechies.
Je ne traite pas les principes dans...
Cliquez pour lire la suite de l'article par tja TECHDAYS PARIS 2010 : SHAREPOINT 2010 POUR LES DéVELOPPEURSTECHDAYS PARIS 2010 : SHAREPOINT 2010 POUR LES DéVELOPPEURS par ROMELARD Fabrice
Animé par: Laurent Cotton Le développement dans SharePoint 2010 passe par plusieurs axes qui seront évoqués dans cette session, mais plus particulièrement les développements simples lié au besoin Business Business Connectivity Services Ce BCS es...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2010 : PLEINIèRE DERNIER JOURTECHDAYS PARIS 2010 : PLEINIèRE DERNIER JOUR par ROMELARD Fabrice
Cette session est la dernière pleinière de ces 3 jours de TechDays Paris 2010. Généralement, cette troisième journée est plus axée sur l'avenir vu par Microsoft. Après un retour sur l'avenir vu par la Science Fiction ou par ...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Forum
CAST DE POINTEURSCAST DE POINTEURS par zaraki21
Cliquez pour lire la suite par zaraki21 CARTE GOOGLECARTE GOOGLE par ja92
Cliquez pour lire la suite par ja92 RE : WIN APIRE : WIN API par omarino_007
Cliquez pour lire la suite par omarino_007
Logiciels
DB-MAIN (9.1.0)DB-MAIN (9.1.0)DB-MAIN is a data-modeling and data-architecture tool. It is designed to help developers and anal... Cliquez pour télécharger DB-MAIN Xilisoft DPG Convertisseur (5.1.37.0120)XILISOFT DPG CONVERTISSEUR (5.1.37.0120)Xilisoft DPG Convertisseur offre aux fans de Nintendo DS une bonne solution leur permettant de dé... Cliquez pour télécharger Xilisoft DPG Convertisseur GraphicsGale (2.01.01)GRAPHICSGALE (2.01.01)GraphicsGale est un logiciel de PixelArt avec de nombreuse fonctionnalités permettant de réalisé ... Cliquez pour télécharger GraphicsGale Architecte 3D (Platinum 2010)ARCHITECTE 3D (PLATINUM 2010)Architecte 3D Platinium vous permet de concevoir facilement les plans votre future maison, de l'é... Cliquez pour télécharger Architecte 3D TeamViewer 5 (TeamViewer 5)TEAMVIEWER 5 (TEAMVIEWER 5)Dépanner un ami,expliquer une manipulation devient un jeu d'enfant.
Prise en main d'un autre ord... Cliquez pour télécharger TeamViewer 5
|