C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: WMI на 64 приложения  (Прочитано 1792 раз)
ДмитрийЛАСТ
Участник


Сказали спасибо: +3/-0
Offline

Сообщений: 11


WMI на 64 приложения
« : 02 Март 2015, 12:31:01 »

Здравствуйте! Подскажите, пожалуйста, как вывести список 64 разрядных приложений. Пока сделал так:
Код:
TGlav_Form *Glav_Form;
//---------------------------------------------------------------------------
    HRESULT hres;
    IWbemLocator *pLoc = NULL;
    IWbemServices *pSvc = NULL;
    IEnumWbemClassObject* pEnumerator = NULL;
    IWbemClassObject *pclsObj;
    ULONG uReturn = 0;
    VARIANT vtProp;
    HRESULT hr;
 
char *AllWmiProgram[] =
        {
            "Name",
            //"AssignmentType",
            "Caption",
            "Description",
            "IdentifyingNumber",
            "InstallDate",
            //"InstallDate2",
            "InstallLocation",
            //"InstallState",
            "HelpLink",
            "HelpTelephone",
            "InstallSource",
            "Language",
            "LocalPackage",
            "PackageCache",
            "PackageCode",
            "PackageName",
            "ProductID",
            "RegOwner",
            "RegCompany",
            "SKUNumber",
            "Transforms",
            "URLInfoAbout",
            "URLUpdateInfo",
            "Vendor",
            //"WordCount",
            "Version"
        };
Код:
__fastcall TGlav_Form::TGlav_Form(TComponent* Owner)
    : TForm(Owner)
{
    CoInitialize(NULL);
    /*hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (hres != S_OK) {
        Application->MessageBoxW(L"Ошибка в инициализации библиотеки COM...",
                                 L"Ошибка в инициализации библиотеки COM...",
                                 MB_OK + MB_ICONERROR + MB_APPLMODAL + MB_TOPMOST);
        return;
    }*/
    //-----------------------------------------------------------------------
    hres = CoInitializeSecurity(
                                NULL,
                                -1,                          // COM authentication
                                NULL,                        // Authentication services
                                NULL,                        // Reserved
                                RPC_C_AUTHN_LEVEL_PKT,       // Default authentication
                                RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
                                NULL,                        // Authentication info
                                EOAC_NONE,                   // Additional capabilities
                                0                            // Reserved
                                );
    if (hres != S_OK) {
        Application->MessageBoxW(L"Ошибка в инициализации защиты...",
                                 L"Ошибка в инициализации защиты...",
                                 MB_OK + MB_ICONERROR + MB_APPLMODAL + MB_TOPMOST);
        CoUninitialize();
        Application->Terminate();
    }
}
Код:
void __fastcall TGlav_Form::InitializationWMI(TStrings *lpList, String wsClass, int typeWMI)
{
    hres = CoCreateInstance(
                            CLSID_WbemAdministrativeLocator,
                            NULL,
                            CLSCTX_INPROC_SERVER,
                            IID_IWbemLocator, (LPVOID *)&pLoc);
    if (hres != S_OK) {
        Application->MessageBoxW(L"Ошибка в создании IWbemLocator объекта...",
                                 L"Ошибка в создании IWbemLocator объекта...",
                                 MB_OK + MB_ICONERROR + MB_APPLMODAL + MB_TOPMOST);
        CoUninitialize();
        return;
    }
    //-----------------------------------------------------------------------
    String wsNamespace = L"root\\cimv2";
    hres = pLoc->ConnectServer(
                                wsNamespace.t_str(),     // Object path of WMI namespace
                                NULL,                    // User name. NULL = current user
                                NULL,                    // User password. NULL = current
                                0,                       // Locale. NULL indicates current
                                NULL,                    // Security flags.
                                0,                       // Authority (for example, Kerberos)
                                0,                       // Context object
                                &pSvc                    // pointer to IWbemServices proxy
                                );
    if (hres != S_OK) {
        Application->MessageBoxW(L"Ошибка в соединении с сервером ROOT\\CIMV2...",
                                 L"Ошибка в соединении с сервером ROOT\\CIMV2...",
                                 MB_OK + MB_ICONERROR + MB_APPLMODAL + MB_TOPMOST);
        pLoc->Release();
        CoUninitialize();
        return;
    }
    //-----------------------------------------------------------------------
    hres = CoSetProxyBlanket(
                            pSvc,                        // Indicates the proxy to set
                            RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
                            RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
                            NULL,                        // Server principal name
                            RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx
                            RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
                            NULL,                        // client identity
                            EOAC_NONE                    // proxy capabilities
                            );
    if (hres != S_OK) {
        Application->MessageBoxW(L"Ошибка в наборе прокси...",
                                 L"Ошибка в наборе прокси...",
                                 MB_OK + MB_ICONERROR + MB_APPLMODAL + MB_TOPMOST);
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return;
    }
    //-----------------------------------------------------------------------
    String wsWQL = L"WQL";
    String wsQuery = String( L"Select * from " + wsClass);
    hres = pSvc->ExecQuery(
                            wsWQL.t_str(),
                            wsQuery.t_str(),
                            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
                            NULL,
                            &pEnumerator);
    if (hres != S_OK) {
        Application->MessageBoxW(L"Ошибка в WQL-запросе...",
                                 L"Ошибка в WQL-запросе...",
                                 MB_OK + MB_ICONERROR + MB_APPLMODAL + MB_TOPMOST);
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return;
    }
    //-----------------------------------------------------------------------
    while (pEnumerator) {
        HRESULT hr = pEnumerator->Next(
                                        WBEM_INFINITE,
                                        1,
                                        &pclsObj,
                                        &uReturn);
 
        if (0 == uReturn) break;
 
        //Чтение и запись параметров
 
        if (typeWMI == 0) {
 
            for (int i = 0; AllWmiOperationSystem[i]; i++) {
                Application->ProcessMessages();
                try {
                    String Strochka = AllWmiOperationSystem[i];
                    hr = pclsObj->Get(Strochka.t_str(), 0, &vtProp, 0, 0);
                    if (hr != S_OK) break;
                    lpList->Add(String(AllWmiOperationSystemCaption[i]) + vtProp.bstrVal);
                } catch (...) {
                    break;
                }
            }
 
        }
        if (typeWMI == 1) {
            lpList->Add("");
            for (int i = 0; AllWmiProgram[i]; i++) {
                Application->ProcessMessages();
                try {
                    String Strochka = AllWmiProgram[i];
                    //ShowMessage(Strochka);
                    hr = pclsObj->Get(Strochka.t_str(), 0, &vtProp, 0, 0);
                    if (hr != S_OK) break;
                    lpList->Add(String(AllWmiProgramCaption[i]) + vtProp.bstrVal);
                } catch (...) {
                    break;
                }
            }
 
        }
        VariantClear(&vtProp);
        pclsObj->Release();
    }
    //-----------------------------------------------------------------------
 
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    if (!pclsObj) pclsObj->Release();
    CoUninitialize();
    return;
}
//---------------------------------------------------------------------------
Читал Requesting WMI Data on a 64-bit Platform, но пример на VB.
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: WMI на 64 приложения
« Ответ #1 : 03 Март 2015, 14:07:11 »

Глянь здесь - отличная статья по теме. Автор утверждает, что получение списка прог средствами WMI работает междленно, быстрее всего через реестр ОС. Там описано три способа (WMI, MSI, реестр).

Чтобы получить список 64-битных приложений, надо вместо ветки "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall" тягать ветку "HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall", остальной код без изменений.
Записан
ДмитрийЛАСТ
Участник


Сказали спасибо: +3/-0
Offline

Сообщений: 11


Re: WMI на 64 приложения
« Ответ #2 : 12 Март 2015, 19:39:30 »

За подсказку спасибо!
Есть еще вопрос:
использую следующую конструкцию
Код:
char *AllMsiProgram[] =
{
"INSTALLPROPERTY_INSTALLEDPRODUCTNAME",
"INSTALLPROPERTY_INSTALLDATE",
"INSTALLPROPERTY_INSTALLLOCATION",
"INSTALLPROPERTY_HELPLINK",
"INSTALLPROPERTY_HELPTELEPHONE",
"INSTALLPROPERTY_INSTALLSOURCE",
"INSTALLPROPERTY_INSTALLEDLANGUAGE",
"INSTALLPROPERTY_LOCALPACKAGE",
/*"ProductID",
"RegCompany",
"RegOwner",*/
"INSTALLPROPERTY_URLINFOABOUT",
"INSTALLPROPERTY_URLUPDATEINFO",
"INSTALLPROPERTY_PUBLISHER",
"INSTALLPROPERTY_VERSIONSTRING"
};

size_t const StrGuidBuffSize = 255;
wchar_t ProductCode[StrGuidBuffSize];
wchar_t ReturnInfo[StrGuidBuffSize];
UINT Index = 0;
String errResult;
DWORD max = 255;
while (0 == MsiEnumProductsW(Index, &ProductCode[0])) {
for (int i = 0; AllMsiProgram[i]; i++) {
String Strochka = (String)AllMsiProgram[i];
ShowMessage(Strochka);
MsiGetProductInfoW(ProductCode, Strochka.t_str(), ReturnInfo,&max);
char *SrcStr = new char[255];
memmove(SrcStr, ReturnInfo, 255);
String Strochka1 = (String)SrcStr;
ShowMessage(Strochka1);
//lpList->Add(/*String(AllMsiProgramCaption[i]) + *//*ReturnInfo);
}
++Index;
}
В результате в списке получаю абра-кадабру. Как правильно реализовать?
Проверял Strochka. Значение получает. А ReturnInfo ничего путем не возвращает.
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


« Ответ #3 : 13 Март 2015, 11:51:54 »

Держи проект, я добр сегодня  
Там реализованы 3 метода получения списка приложений: через WMI, MSI и реестр.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  




....

Powered by SMF 1.1.21 | SMF © 2025, Simple Machines
Страница сгенерирована за 0.109 секунд. Запросов: 19.