MsiViewFetch“SELECT * FROM `Property`”成功,但在C++中返回“Incorrect function.”

4xy9mtcn  于 2024-01-09  发布在  其他
关注(0)|答案(2)|浏览(132)

我想读取一个msi文件的属性表。该表显示正确。
这是一个调用和(部分)输出:

  1. >ReadMsiProperties.exe evince-2.32.0.145.msi
  2. (MsiOpenDatabase The operation completed successfully.)
  3. (MsiViewFetch Incorrect function.) WixAppFolder = WixPerUserFolder
  4. (MsiViewFetch Incorrect function.) WixUIRMOption = UseRM
  5. (MsiViewFetch Incorrect function.) WIXUI_INSTALLDIR = APPLICATIONFOLDER
  6. (MsiViewFetch Incorrect function.) ALLUSERS = 2

字符串
MsiViewFetch成功,但返回“Incorrect function”。这是来自winerror.h的错误代码% 1(ERROR_INVALID_FUNCTION)
我假设我错过了一些东西,不想忽略错误。
我试过调试,但似乎无法调试到MsiViewFetch。
有人有提示吗?
谢谢你,马库斯
这就是代码:

  1. // Requirements: Add Msi.lib to "Resource Files"
  2. #include "stdafx.h"
  3. #include <windows.h>
  4. #include <msi.h>
  5. #include <msiquery.h>
  6. MSIHANDLE hDB;
  7. MSIHANDLE hViewSELECT;
  8. MSIHANDLE hRecord;
  9. TCHAR svPropname[256];
  10. TCHAR svPropvalue[256];
  11. DWORD nBuffer;
  12. UINT errorI;
  13. _TCHAR errorM[256];
  14. void errorCode2char (UINT error, _TCHAR *buf) {
  15. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
  16. // chop \r\n
  17. if (buf[_tcslen(buf)-1] = '\n') buf[_tcslen(buf)-1] = '\0';
  18. if (buf[_tcslen(buf)-1] = '\r') buf[_tcslen(buf)-1] = '\0';
  19. }
  20. void _tmain(int argc, _TCHAR* argv[]) {
  21. errorI = MsiOpenDatabase(argv[1], MSIDBOPEN_READONLY, &hDB);
  22. errorCode2char(errorI, errorM);
  23. printf("(MsiOpenDatabase %S)\n", errorM);
  24. if (errorI != ERROR_SUCCESS) return;
  25. MsiDatabaseOpenView(hDB, _T("SELECT `Property`, `Value` FROM `Property`"), &hViewSELECT);
  26. MsiViewExecute(hViewSELECT, NULL);
  27. while (errorI = MsiViewFetch (hViewSELECT, &hRecord) != ERROR_NO_MORE_ITEMS) { // *errorI <-- Incorrect function.
  28. errorCode2char(errorI, errorM);
  29. nBuffer = (DWORD)256; MsiRecordGetString(hRecord, 1, svPropname, &nBuffer);
  30. nBuffer = (DWORD)256; MsiRecordGetString(hRecord, 2, svPropvalue, &nBuffer);
  31. printf("(MsiViewFetch %S) %S = %S\n", errorM, svPropname, svPropvalue);
  32. }
  33. MsiViewClose(hViewSELECT);
  34. MsiDatabaseCommit(hDB);
  35. MsiCloseHandle(hViewSELECT);
  36. MsiCloseHandle(hDB);
  37. }

vfhzx4xs

vfhzx4xs1#

这里是错误的地方errorI持有,返回值的API(MsiOpenDatabase)

  1. while(errorI = MsiViewFetch (hViewSELECT, &hRecord) != ERROR_NO_MORE_ITEMS)

字符串
使用while (ERROR_NO_MORE_ITEMS != MsiViewFetch(hView, &hRecord))可以解决此错误。

0s7z1bwu

0s7z1bwu2#

编码错误会扭曲MsiViewFetch的返回代码,未扭曲的返回代码为0(对于ERROR_SUCCESS)。
在C++中,比较(!=)优先于直接赋值(=)。
因此,一份声明

  1. while (a = b != c)

字符串
被解释为

  1. while (a = (b != c))


我可不想这样。
通过插入括号来更正程序

  1. while ((a = b) != c)


明确地

  1. while ((errorI = MsiViewFetch(hViewSELECT, &hRecord)) != ERROR_NO_MORE_ITEMS)

展开查看全部

相关问题