2012-03-12 15 views
1

我編寫了以下腳本來枚舉MSI的已安裝產品。在NSIS腳本的Ms :: EnumProducts和GetLastError的System :: call中獲取錯誤結果

!include LogicLib.nsh 

!define MsiGetProductCodeFromName "!insertmacro MsiGetProductCodeFromName" 

!macro MsiGetProductCodeFromName MSINSISPRODUCTNAME 
     Push ${MSINSISPRODUCTNAME} 
     Call MsiGetProductCodeFromName 
!macroend 

Function MsiGetProductCodeFromName 
    ;================ 
    ; Stack : <ProductName>, ... 
    ;================ 

    Exch $0   ; ProductName 
    Push $1   ; For internal use as buffer for ProductCode 
    Push $2   ; For internal use as counter to MsiEnumProducts 
    Push $3   ; For internal use as result of MsiEnumProducts 

    ; loop through all productcodes 
    Strcpy $2 0 

    System::Call "advapi32::GetUserName(t .r0, *i ${NSIS_MAX_STRLEN} r1) i.r2" 
    DetailPrint "User name - $0" 
    DetailPrint "String length - $1" 
    DetailPrint "Return value - $2" 

    loop: 
    DetailPrint "Calling MsiEnumProducts ($2, $1)" 
    System::call "msi::MsiEnumProducts (i r2, t .r1) i.r3" 
    DetailPrint "Result = $3" 
    System::call "kernel32::GetLastError() i.r3" 
    DetailPrint "LastError = $3" 
    ${If} $R1 == 0 
      DetailPrint $1 
      Intop $R0 $R0 + 1 
      goto loop 
    ${Endif} 

    end: 

    Pop $3 
    Pop $2 
    Exch 
    Pop $0 

    ;========================= 
    ; Stack : <ProductCode>, ... 
    ; ======================== 
FunctionEnd 

當我使用上面的腳本以下列方式:

${MsiGetProductCodeFromName} ${PRODUCT_NAME} 

我得到以下輸出:

Calling MsiEnumProducts(0,) 
Result = error 
LastError = error 
Completed 

請注意,這是不包括系統調用的輸出GetUserName,它工作正常。

任何幫助,將不勝感激。

回答

1

對MsiEnumProducts的第一個調用必須從索引0開始,因此在循環標籤前添加Strcpy $2 0

我不確定dll :: function和()之間是否有空格,當你剛剛從系統插件中得到「錯誤」時,通常意味着語法有問題。

不能調用KERNEL32:GetLastError函數,並得到有效的結果,它必須是原始呼叫的一部分:System::Call 'dll::function() ?e'然後彈出錯誤代碼從堆棧...