2014-02-22 43 views
1

我想讀取一個MSI文件的Propery表。 該表顯示correclty。MsiViewFetch「SELECT * FROM`Property`」成功,但返回「不正確的函數。」在C + +

這是呼叫和輸出(的一部分):

>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是succesfull但返回 「不正確的功能。」 這是來自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); 
} 
+0

乍一看,這看起來不錯糾正,但一定出事了。你對'MsiDatabaseOpenView'和'MsiViewExecute'的調用返回什麼?如果'MsiDatabaseOpenView'成功,'hViewSELECT'中有什麼? –

+0

嗨Michael,根本原因是C++,而不是Msi。我需要說** while((errorI = MsiViewFetch(hView,&hRecord))!= ERROR_NO_MORE_ITEMS)**雖然我還不明白爲什麼。關於你的問題:一切正常,只有errorI的值被扭曲:-) – Markus

+0

爲什麼沒有優先規則救我? **(a = b!= c){} **不同於** while((a = b)!= c){} **。 – Markus

回答

0

的編碼錯誤扭曲MsiViewFetch的返回代碼,這不失真爲0(對於ERROR_SUCCESS)。

在C++中,比較(!=)優先於直接賦值(=)。

因此,聲明

while (a = b != c) 

被解釋爲

while (a = (b != c)) 

這是不是我的本意。

該方案是通過插入支架

while ((a = b) != c) 

explicetely

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