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

4xy9mtcn  于 9个月前  发布在  其他
关注(0)|答案(2)|浏览(110)

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

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

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

// Requirements: Add Msi.lib to "Resource Files" 

#include "stdafx.h"
#include <windows.h>
#include <msi.h>
#include <msiquery.h>

MSIHANDLE hDB;
MSIHANDLE hViewSELECT;
MSIHANDLE hRecord; 
TCHAR  svPropname[256];
TCHAR  svPropvalue[256]; 
DWORD nBuffer;
UINT errorI;
_TCHAR errorM[256];

void errorCode2char (UINT error, _TCHAR *buf) {
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
    // chop \r\n
    if (buf[_tcslen(buf)-1] = '\n') buf[_tcslen(buf)-1] = '\0';
    if (buf[_tcslen(buf)-1] = '\r') buf[_tcslen(buf)-1] = '\0';
}

void _tmain(int argc, _TCHAR* argv[]) {
    errorI = MsiOpenDatabase(argv[1], MSIDBOPEN_READONLY, &hDB);
    errorCode2char(errorI, errorM);
    printf("(MsiOpenDatabase %S)\n", errorM);
    if (errorI != ERROR_SUCCESS) return;

    MsiDatabaseOpenView(hDB, _T("SELECT `Property`, `Value` FROM `Property`"), &hViewSELECT);
    MsiViewExecute(hViewSELECT, NULL);
    while (errorI = MsiViewFetch (hViewSELECT, &hRecord)  != ERROR_NO_MORE_ITEMS) { // *errorI <-- Incorrect function.
        errorCode2char(errorI, errorM);
        nBuffer = (DWORD)256; MsiRecordGetString(hRecord, 1, svPropname, &nBuffer);
        nBuffer = (DWORD)256; MsiRecordGetString(hRecord, 2, svPropvalue, &nBuffer);
        printf("(MsiViewFetch %S)  %S = %S\n", errorM, svPropname, svPropvalue);
    }
    MsiViewClose(hViewSELECT);
    MsiDatabaseCommit(hDB);
    MsiCloseHandle(hViewSELECT);
    MsiCloseHandle(hDB);
}

vfhzx4xs

vfhzx4xs1#

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

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

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

0s7z1bwu

0s7z1bwu2#

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

while (a = b != c)

字符串
被解释为

while (a = (b != c))


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

while ((a = b) != c)


明确地

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

相关问题