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
Objet ActiveX (COM) sous C++ (Visual C++ ou pas) [ par Raksmey ]
Bonjour, Je viens à vous pour une question d'ordre général sur la création des objets ActiveX. Je me demandais si certans d'entre vous connaissez un
ole./com ou sprintf/scanf????????? [ par amouretsu ]
bONJOUR POUVEZ VOUS M4AIDER SVP en faite mon application consiste a devoopper une application qui genere un code c++ a partir d'un document word mon
Interdire modification registre [ par zuddap ]
Bonjour a tous, voila mon problème est que dans mon entreprise, les utilisateur disposé de PC avec des session admin bridé par des GPO, j'aimerais i
selection automatique d'un port série [ par flozzzzz ]
bonjour, je suis stagiaire dans un bureau d'étude et je dois faire des modifications / améliorations d'un programme déjà existant. Je n'ai pas vraime
[BAR]Installer un template CSS sur mon site e-monsite.com [ par sanasoke ]
Bonsoir . je m'y connais pas mal en informatique mais je ne connais pas grand chose en programmation. Je voudrais installer un template sur mon site
Lecture d'info depuis le port COM avec MS-Access [ par yves64 ]
Bonjour, J'ai une application Access qui doit recevoir des données d'un chronomètre externe relié au PC par le port COM. Jusqu'ici, j'utilisais le MSc
Code d'un mini compilateur en C [ par achrefpdg ]
[^^happy10] Salut les amis y a t il quelqu' un qui peut m'aider de corriger ce code source de mini compilateur . Voila le lien http://www.4shared.com/
|
Derniers Blogs
WORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBEWORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBE par JeremyJeanson
Depuis déjà un an, je conseille vivement les utilisateurs de Workflow Foundation 3 à migrer vers la version 4. L'information qui va suivre ne devrait donc pas trop prendre au dépourvu les personnes qui l'ont sagement suivi. Je profite de ce poste pour fai...
Cliquez pour lire la suite de l'article par JeremyJeanson TECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PCTECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PC par ROMELARD Fabrice
Speakers: Thierry Rapatout, Antoine Petit et Xavier Trebbia Cette session entre dans le cadre des RDV Décideurs des TechDays 2012, elle est liée à la consumérisation de l'IT et la mise en place du "DeskTop as a Service" dans de plus en ...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : SYSTEM CENTER SERVICE MANAGER 2012 VUE D'ENSEMBLETECHDAYS PARIS 2012 : SYSTEM CENTER SERVICE MANAGER 2012 VUE D'ENSEMBLE par ROMELARD Fabrice
Speakers: Julien Marechal, Gautier Confiant, Sébastien MEYER La session débute par le positionnement de la solution System Center par rapport aux concepts d'organisation ITIL. Le portail du catalogue de se...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : PLEINIèRE SECOND JOURTECHDAYS PARIS 2012 : PLEINIèRE SECOND JOUR par ROMELARD Fabrice
Après une première journée dédiée aux développeurs, cette seconde journée est dédiée au monde des entreprises et de ses applications. Ainsi, cette pleinière est dédiée à faire un 360 de l'évolution des applications Business aux demandes ac...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : RETOUR D'EXPéRIENCE SUR LA MISE EN PLACE D'UN CLOUD PRIVéTECHDAYS PARIS 2012 : RETOUR D'EXPéRIENCE SUR LA MISE EN PLACE D'UN CLOUD PRIVé par ROMELARD Fabrice
Speaker : Guillaume Rochette Cette session est dédiée à fournir le retour sur la mise en place d'un cloud privé (IaaS) par Osiatis pour son compte ou celui de ses clients. Ce projet s'est déroulé sur 4 mois et a permis de faire évoluer...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|