Результат получения ошибки в System :: call для MsiEnumProducts и GetLastError в сценарии NSIS - PullRequest
1 голос
/ 12 марта 2012

Я написал следующий скрипт для перечисления установленных продуктов от MSI.

!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 Ответ

2 голосов
/ 12 марта 2012

Первый вызов MsiEnumProducts должен начинаться с индекса 0, поэтому добавьте Strcpy $2 0 перед меткой цикла.

Я не уверен, что между dll :: function и () может быть пробел., когда вы просто получаете «error» из системного плагина, это обычно означает, что с синтаксисом что-то не так.

Вы не можете вызвать kernel32 :: GetLastError и получить действительный результат, он должен быть частью оригиналавызовите System::Call 'dll::function() ?e', а затем вытолкните код ошибки из стека ...

...