0

前の質問への回答と同様のコードを使用して、システム プラグイン経由でシステム情報を取得しています。API 関数は、ワイド char 文字列を返す (または返さない) ことを除いて、非常によく似ています。

ドメインのメンバーであるコンピューターでそのスクリプトを使用している間、テストのブランチで logiclib テストが常にパスする理由がわかりません${else}。次のキャプチャは、$1null ではないことを示しています。

可変ダンプ

NetGetDCName リファレンスをさらに読みながら、ワイド char 文字列ポインタではなく、関数の戻り値を確認する方が望ましいと思います。私は少し混乱しています。なぜ${If} 0 <> $1いつも失敗するのですか? $1この場合、等しいドメインのメンバーではない仮想マシンをチェックしました0${IfThen}では、メモリを解放するテストも間違っていると思います。

サンプルコードは次のとおりです。

!include "logiclib.nsh"
outfile "hello2.exe"

!define DEBUG `System::Call kernel32::OutputDebugString(ts)`

section

    Call GetDCName
    pop $0

    Messagebox MB_OK "DCName=$0"

sectionEnd

Function GetDCName
    ;Push the domain controler name to the stack (or an empty string if no dc)
    push $0
    push $1
    push $2
    System::Call "netapi32::NetGetDCName(i0, i0, *w 0 r1) i.r2"
    Dumpstate::debug
    ${If} 0 <> $1
        ${debug} "copy $1"
        StrCpy $0 $1
    ${else}
        ${debug} "copy empty string"
        StrCpy $0 ""
    ${endif}
    ${IfThen} $1 <> 0 ${|} System::Call "netapi32::NetApiBufferFree(ir1)" ${|}
    Pop $2
    Pop $1
    Exch $0
FunctionEnd

編集:アンダースのおかげで、ここに修正された関数があります:

Function GetDCName
    ;Push the domain controler name to the stack (or an empty string if no dc)
    push $0
    push $1
    push $2
    System::Call "netapi32::NetGetDCName(i0, i0, *i 0 r1) i.r2" ;do not convert r1 to wchar, keep the pointer to free it
    ${If} $2 = 0
        System::Call "*$1(&w${NSIS_MAX_STRLEN} .r0)"        ;get the wchar from the pointer
        ${IfThen} $1 <> 0 ${|} System::Call "netapi32::NetApiBufferFree(ir1)" ${|}  ;free the pointer
    ${else}
        StrCpy $0 ""
    ${endif}
    Pop $2
    Pop $1
    Exch $0
FunctionEnd
4

1 に答える 1

0

演算子は、<>文字列ではなく数値用です。ただし、これはあなただけの問題ではありません。*(通常) のみで使用でき、 / /では使用iできません。/ /型は C スタイルの文字列との間で変換されますが、実際のメモリ アドレスは free 関数に渡す必要があるため必要です。tmwtmw

NetGetDCNameに渡す必要があり*i0r1、$2 が 0 の場合、構造体構文 (*$1(&w${NSIS_MAX_STRLEN}.r5)または*$1(w.r5)) を使用して文字列を抽出し、最後に $1 をそのまま free 関数に渡すことができます...

于 2012-09-13T09:17:49.550 に答える