2012-03-12 7 views
1

MSIからインストールされた製品を列挙するためのスクリプトを作成しました。NSISスクリプトでMsiEnumProductsと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と()の間にスペースを入れることができない場合は、システムプラグインから「エラー」が発生したときに通常は構文に問題があることを意味します。 ...

System::Call 'dll::function() ?e'、その後、スタックからのエラーコードをポップ:

あなたはkernel32の呼び出し:: GetLastError関数と有効な結果を得ることができない、それは元のコールの一部である必要があります

関連する問題