Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.68/19: Рейтинг темы: голосов - 19, средняя оценка - 4.68
Марсианин)))
713 / 46 / 15
Регистрация: 18.07.2010
Сообщений: 637

Ошибка при использовании MsiEnumProducts

28.08.2014, 19:09. Показов 3820. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем Добрый вечер.

Ребята проблема такая, написал код, но при компиляции выдает ошибки
Code
1
2
3
4
5
6
7
8
[bcc32 Error] msi.h(776): E2015 Ambiguity between 'PHKEY' and 'Winapi::Windows::PHKEY'
  Full parser context
    Unit1.cpp(4): #include c:\program files (x86)\embarcadero\rad studio\11.0\include\windows\sdk\msiquery.h
    msiquery.h(23): #include c:\program files (x86)\embarcadero\rad studio\11.0\include\windows\sdk\msi.h
[bcc32 Error] msi.h(781): E2015 Ambiguity between 'PHKEY' and 'Winapi::Windows::PHKEY'
  Full parser context
    Unit1.cpp(4): #include c:\program files (x86)\embarcadero\rad studio\11.0\include\windows\sdk\msiquery.h
    msiquery.h(23): #include c:\program files (x86)\embarcadero\rad studio\11.0\include\windows\sdk\msi.h
Сам код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <msiquery.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
typedef UINT (WINAPI *MyMsiEnumProducts)(DWORD iProductIndex, LPTSTR lpProductBuf);
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    HINSTANCE hUser = NULL;
    hUser =  LoadLibraryA("Msi.dll");
    if (hUser != NULL)
    {
       MyMsiEnumProducts filter = (MyMsiEnumProducts)GetProcAddress(hUser, "MsiEnumProducts");
       
       if (filter != NULL)
       {
          CHAR ProductCode[40];
          UINT nResult;
          AnsiString errResult;
               
          for (int nIndex = 0;;nIndex++)
          {
             nResult = MsiEnumProducts(nIndex,ProductCode);
             
             if (nResult != ERROR_SUCCESS)
             {
                if (nResult == 1610)
                   errResult = "ERROR_BAD_CONFIGURATION";
                if (nResult == 87)
                   errResult = "ERROR_INVALID_PARAMETER";
                if (nResult == 259)
                   errResult = "ERROR_NO_MORE_ITEMS";
                if (nResult == 8)
                   errResult ="ERROR_NOT_ENOUGH_MEMORY";
              
                break;
             }
             Memo1->Lines->Add(AnsiString(nIndex) + " " +AnsiString(ProductCode) );
          }
        }
       FreeLibrary(hUser);
    }
 
 
}
//---------------------------------------------------------------------------
Radstudio XE4

Добавлено через 2 часа 24 минуты
Это ошибка возникает когда даже просто подключаю
C++
1
#include <msiquery.h>
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.08.2014, 19:09
Ответы с готовыми решениями:

Ошибка при использовании парсера
Нашёл статью: http://www.rsdn.ru/article/files/Classes/tparser.xml Там есть пример использования парсера. НО при попытке...

Ошибка при использовании конструктора
Вот написал часть программы на С++, захотел проверить, но выбило ошибку Unit1.cpp(104): E2294 Structure required on left side of . or .*...

Ошибка при использовании класса
Решил написать чат. Написал маленький класс сервера: class ServChat { private: unsigned int unNumber; unsigned int umNumber; ...

27
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33398 / 21508 / 8236
Регистрация: 22.10.2011
Сообщений: 36,906
Записей в блоге: 12
28.08.2014, 19:21
Поменяй инклуды местами:

C++
1
2
3
4
#include <windows.h>
#include <msiquery.h>
 
#include <vcl.h>
, и еще, чтобы код продолжил компилироваться, замени в 31-ой строке CHAR на TCHAR, иначе будет зависимость от настроек компилятора...

А в 37-ой строке вместо MsiEnumProducts должен быть filter, тебе не кажется?
2
Марсианин)))
713 / 46 / 15
Регистрация: 18.07.2010
Сообщений: 637
28.08.2014, 22:17  [ТС]
Спасибо работает.
Но возникла другая проблема. У меня установлено около 60 программ, но код выдал всего 53.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 
     UINT nResult;
     DWORD max = 255;
     TCHAR buffer[255];
     AnsiString errResult;
     for (int nIndex = 0;;nIndex++)
     {
          TCHAR ProductCode[40];
          nResult = MsiEnumProducts(nIndex,ProductCode);
          if (nResult != ERROR_SUCCESS)
          {
               if (nResult == 1610)
                    errResult = "ERROR_BAD_CONFIGURATION";
               if (nResult == 87)
                    errResult = "ERROR_INVALID_PARAMETER";
               if (nResult == 259)
                    errResult = "ERROR_NO_MORE_ITEMS";
               if (nResult == 8)
                    errResult ="ERROR_NOT_ENOUGH_MEMORY";
               Memo1->Lines->Add(AnsiString(errResult) );
               break;
         }
                 // при вставки INSTALLPROPERTY_INSTALLLOCATION не у всех выводило место локализации.
         MsiGetProductInfoA(ProductCode,INSTALLPROPERTY_INSTALLEDPRODUCTNAME,buffer,&max);
         Memo1->Lines->Add(AnsiString(nIndex) +"  " +AnsiString(ProductCode) + " " +AnsiString(buffer) );
    }
}
Запускал от имени администратора.

В чем может быть причина?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33398 / 21508 / 8236
Регистрация: 22.10.2011
Сообщений: 36,906
Записей в блоге: 12
29.08.2014, 00:52
Лучший ответ Сообщение было отмечено Убежденный как решение

Решение

Цитата Сообщение от Dr.Xank Посмотреть сообщение
У меня установлено около 60 программ, но код выдал всего 53
Вот именно поэтому все и используют чтение ветки реестра. Ни один из столь широко разрекламированных в интернете кодов (включая и код с MSDN Blogs) не дает полного списка установленных программ. А чтение реестра - дает...
2
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.08.2014, 09:50
Цитата Сообщение от Dr.Xank Посмотреть сообщение
У меня установлено около 60 программ, но код выдал всего 53.
У меня аналогичный код на Visual C++ всегда выдает полный список.
Правда, я использую unicode-версии функций - MsiEnumProductsW и MsiGetProductInfoW.
1
Марсианин)))
713 / 46 / 15
Регистрация: 18.07.2010
Сообщений: 637
29.08.2014, 19:15  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
У меня аналогичный код на Visual C++ всегда выдает полный список.
Правда, я использую unicode-версии функций - MsiEnumProductsW и MsiGetProductInfoW.
А вы не могли бы выложить пробный-проект? Если можно объясните как подключать какие либо длл или либы.
Хочу проверить на своей системы.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.08.2014, 20:20
Цитата Сообщение от Dr.Xank Посмотреть сообщение
Но возникла другая проблема. У меня установлено около 60 программ, но код выдал всего 53.
А в панели управления видны все 60 ?
0
Почемучка)
 Аватар для Ddv122
1244 / 304 / 30
Регистрация: 23.12.2010
Сообщений: 2,001
Записей в блоге: 1
29.08.2014, 20:36
Avazart,
на windows 8.1 x64 + BCB6 - видны тоже не все (далеко не все(30 с копиями из 69))
0
Марсианин)))
713 / 46 / 15
Регистрация: 18.07.2010
Сообщений: 637
29.08.2014, 20:41  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
А в панели управления видны все 60 ?
Я от туда и считал. То есть Удалить или изменить программу, там 60.

Убежденный,
Я вас прошу, не могли бы вы выложить проект на VSc++
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.08.2014, 21:43
Типа такого:
C++
1
2
3
4
5
6
7
8
9
10
size_t const StrGuidBuffSize = 39;
wchar_t Buffer[StrGuidBuffSize];
UINT Index = 0;
 
while (0 == MsiEnumProductsW(Index, &Buffer[0]))
{
    ++Index;
}
 
printf("Installed programs = %lu.\r\n", Index);
У меня в "Program and Components" (Win7 x64) примерно 70 пунктов.
С помощью MsiEnumProducts находится около 130 (включая скрытые).
1
Марсианин)))
713 / 46 / 15
Регистрация: 18.07.2010
Сообщений: 637
30.08.2014, 07:25  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
У меня в "Program and Components" (Win7 x64) примерно 70 пунктов.
С помощью MsiEnumProducts находится около 130 (включая скрытые).
Подтверждаю, у меня 64 нашла. А по чему в Embarcadero не все находит?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
30.08.2014, 09:19
Возможно, причина в этих строчках:
C++
1
2
MsiGetProductInfoA(ProductCode,INSTALLPROPERTY_INSTALLEDPRODUCTNAME,buffer,&max);
Memo1->Lines->Add(AnsiString(nIndex) +"  " +AnsiString(ProductCode) + " " +AnsiString(buffer) );
Например, потому что max не обновляется (а это in/out-параметр, см. доки на функцию).
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33398 / 21508 / 8236
Регистрация: 22.10.2011
Сообщений: 36,906
Записей в блоге: 12
30.08.2014, 13:47
Цитата Сообщение от Убежденный Посмотреть сообщение
Например, потому что max не обновляется
При чем тут max, если приведенный в предыдущем посте код при 93-х установленных программах выдает Installed programs = 53.?
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.08.2014, 14:36
К тому что проверять надо коды возврата функций, может буфера мало под размер строки:

ERROR_MORE_DATA A buffer is too small to hold the requested data.
http://msdn.microsoft.com/en-u... 85%29.aspx

Поэтому:
C++
1
 // при вставки INSTALLPROPERTY_INSTALLLOCATION не у всех выводило место локализации.
Кроме того стоило бы буферы инициализировать нулями, ну или читать именно max - символов (его кстати вероятно тоже нужно инициализировать на каждой итерации)

Добавлено через 27 минут
P.S: У меня в "Программы и управления" 135, прога возвращает 176

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//---------------------------------------------------------------------------
#include <windows.h>
#include <Msi.h>
 
#include <vcl.h>
#pragma hdrstop
 
#pragma comment (lib,"Msi.lib")
 
#include "Unit1.h"
// ---------------------------------------------------------------------------
//  ....
// ---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject* Sender)
{
    Memo1->Clear();
 
    for (int i=0; ;++i)
    {
        TCHAR ProductCode[40]={0};
        unsigned rc= MsiEnumProducts(i,ProductCode);
        switch(rc)
        {
            case ERROR_SUCCESS:
                     break;
            case ERROR_NO_MORE_ITEMS:
                     return;
            case ERROR_BAD_CONFIGURATION:
                     Memo1->Lines->Add("ERROR_BAD_CONFIGURATION");
                     return;
            case ERROR_INVALID_PARAMETER:
                     Memo1->Lines->Add("ERROR_INVALID_PARAMETER");
                     return;
            case ERROR_NOT_ENOUGH_MEMORY:
                     Memo1->Lines->Add("ERROR_NOT_ENOUGH_MEMORY");
                     return;
            default:
                     return;
        }
 
        const unsigned long buf_size= 255;
        TCHAR buffer[buf_size]={0};
        unsigned long size= buf_size;
 
        rc= MsiGetProductInfo(ProductCode,
                                                    INSTALLPROPERTY_INSTALLEDPRODUCTNAME,
                                                    buffer,
                                                    &size);
        switch(rc)
        {
            case ERROR_SUCCESS:
                     break;
            case ERROR_BAD_CONFIGURATION:
                     Memo1->Lines->Add("ERROR_BAD_CONFIGURATION");
                     return;
            case ERROR_INVALID_PARAMETER:
                     Memo1->Lines->Add("ERROR_INVALID_PARAMETER");
                     return;
            case ERROR_MORE_DATA:
                     Memo1->Lines->Add("ERROR_MORE_DATA");
                     return;
            case ERROR_UNKNOWN_PRODUCT:
                     Memo1->Lines->Add("ERROR_UNKNOWN_PRODUCT");
                     return;
            case ERROR_UNKNOWN_PROPERTY:
                     Memo1->Lines->Add("ERROR_UNKNOWN_PROPERTY");
                     return;
            default:
                     return;
        }
 
        Memo1->Lines->Add(String(i)+ "  "+
                                            String(ProductCode)+ " "+
                                            String(buffer)+ " size:"+
                                            String(size));
    }
}
// ---------------------------------------------------------------------------
1
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
30.08.2014, 15:58
Цитата Сообщение от UI Посмотреть сообщение
При чем тут max, если приведенный в предыдущем посте код при 93-х установленных программах выдает Installed programs = 53.?
В 99% случаев причина таких ошибок, которые мы здесь обсуждаем -
кривые руки или невнимательное следование документации. И только 1% -
так всеми любимые "глюки" системы и/или компилятора.
1
Марсианин)))
713 / 46 / 15
Регистрация: 18.07.2010
Сообщений: 637
30.08.2014, 19:56  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
В 99% случаев причина таких ошибок, которые мы здесь обсуждаем -
кривые руки или невнимательное следование документации. И только 1% -
так всеми любимые "глюки" системы и/или компилятора.
Цитата Сообщение от Avazart Посмотреть сообщение
Кроме того стоило бы буферы инициализировать нулями, ну или читать именно max - символов (его кстати вероятно тоже нужно инициализировать на каждой итерации)
Цитата Сообщение от UI Посмотреть сообщение
При чем тут max, если приведенный в предыдущем посте код при 93-х установленных программах выдает Installed programs = 53.?
Оказалось всё очень просто, надо было либу добавлять не через Проект-Адд, а кодом)))
C++
1
 #pragma comment (lib,"Msi.lib")
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33398 / 21508 / 8236
Регистрация: 22.10.2011
Сообщений: 36,906
Записей в блоге: 12
30.08.2014, 20:04
А я либу вообще не добавлял, использовал DLL... Инициализация нулями присутствует, ни фига не помогает, как было 53, так и стоит на 53-х. Что еще не так? Плевать уже на MsiGetProductInfo, мне бы этот код хотя бы количество программ посчитал, куда уж нам до названий... Пряморукие, жду ответа... А то балаболить все умеют, я смотрю. Начиная с MS (нельзя было привести пример использования? На ShowWindow, значит, пример нужен, а на MsiEnumProducts - нет?)
1
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.08.2014, 21:00
Я тестировал только под x32
Цитата Сообщение от Убежденный Посмотреть сообщение
У меня в "Program and Components" (Win7 x64) примерно 70 пунктов.
С помощью MsiEnumProducts находится около 130 (включая скрытые).
Убежденный, Как понимаю тестил под x64 при чем вероятно в сборке x64 под VC++, так что могу лишь предположить что недочет возникает в сборке x32 под x64.

Добавлено через 1 минуту
Цитата Сообщение от Dr.Xank Посмотреть сообщение
Оказалось всё очень просто, надо было либу добавлять не через Проект-Адд, а кодом)))
По идее не должно играть роли, разве что ты выбрал не тот lib файл.
1
Марсианин)))
713 / 46 / 15
Регистрация: 18.07.2010
Сообщений: 637
30.08.2014, 22:07  [ТС]
Похоже вчера плохо считал, оказывается у меня 69 программ, а выводит 64. Нет яндекса(браузер), танчиков и где идет кириллица(((
1
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.08.2014, 22:34
Версия функции? Юникодную вызываешь?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.08.2014, 22:34
Помогаю со студенческими работами здесь

Ошибка при использовании TServerSocket
Здраствуйте, у меня в проекте 2 формы на первой форме есть TServerSocket при отправке текста таким образом ...

Ошибка при использовании ADOConnection
Здравствуйте! Нужна ваша помощь) Щелкаю дважды на ADOConnection1 и, соответственно, нажимаю &quot;Build...&quot;. И тут выскакивает...

Ошибка при использовании экземпляра класса
Всем здравствуйте. Есть класс, суть которого - одна функция записывающая массив вещественных значений в файл с определённым именем (один...

Ошибка при использовании метода Ole Add
При использовании метода OLE Add появляется сообщение об ошибке: Project Project1.exe raised exception class EOleSysError with message 'The...

Ошибка Access Violation при использовании vector внутри класса
Проблема в следующем: имеется пользовательский класс. Три поля в классе - векторы, один из которых двумерный. Первое создание экземпляра...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru