0

我使用类似于我之前问题的答案的代码通过系统插件获取系统信息。API 函数非常相似,只是它返回(或不返回)一个宽字符字符串。

在属于域成员的计算机上使用该脚本时,我无法理解为什么 logiclib 测试总是在${else}测试的分支中通过。以下捕获显示$1不为空:

变量转储

在阅读更多NetGetDCName 参考资料时,我认为最好检查函数返回值而不是宽字符字符串指针。我有点困惑,为什么我的${If} 0 <> $1总是失败?在这种情况下,我检查了一个不是域成员的虚拟机$10我想那么${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不是t// m。//类型w在C 样式字符串之间进行转换,但在您的情况下,您需要实际的内存地址,因为您必须将其传递给 free 函数。tmw

您需要传递*i0r1给 NetGetDCName,然后如果 $2 为 0,那么您可以使用结构语法(*$1(&w${NSIS_MAX_STRLEN}.r5)*$1(w.r5))提取字符串,最后将 $1 原封不动地传递给自由函数...

于 2012-09-13T09:17:49.550 回答