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

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

28.08.2014, 19:09. Показов 3799. Ответов 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
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 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
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 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
8484 / 6151 / 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
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
30.08.2014, 13:47
Цитата Сообщение от Убежденный Посмотреть сообщение
Например, потому что max не обновляется
При чем тут max, если приведенный в предыдущем посте код при 93-х установленных программах выдает Installed programs = 53.?
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 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
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
30.08.2014, 20:04
А я либу вообще не добавлял, использовал DLL... Инициализация нулями присутствует, ни фига не помогает, как было 53, так и стоит на 53-х. Что еще не так? Плевать уже на MsiGetProductInfo, мне бы этот код хотя бы количество программ посчитал, куда уж нам до названий... Пряморукие, жду ответа... А то балаболить все умеют, я смотрю. Начиная с MS (нельзя было привести пример использования? На ShowWindow, значит, пример нужен, а на MsiEnumProducts - нет?)
1
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 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
8484 / 6151 / 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
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru