【问题标题】:How can I convert literal newlines into $\n in NSIS?如何在 NSIS 中将文字换行符转换为 $\n?
【发布时间】:2013-03-16 03:06:26
【问题描述】:

我正在编写一个 NSIS 安装程序,它记录一些外部命令的输出(请参阅 How can I make this function actually work in NSIS?。)不幸的是,当 nsis 存储输出时,它会吃掉文字换行符,大概是因为它正在寻找文字 $\n (我其实不知道。)

谁能告诉我如何在下面的 sn-p 中正确转换 $0 的换行符?

nsExec::ExecToStack '...'
Pop $0

我会将存储的字符串写入文件和 DetailPrint。

【问题讨论】:

  • DetailPrint 确实吃换行符。您必须按$\nDetailPrint 每行进行拆分。不知道为什么你看到这个FileWrite虽然......
  • 嗯,我正在使用一个函数来读取安装日志并为此使用 filewrite,所以这就是发生这种情况的原因

标签: nsis


【解决方案1】:

我不相信 ExecToStack 会吃换行符,但它仅限于 ${NSIS_MAX_STRLEN} 的输出。

ExecDos plug-in 有一个 /TOFUNC 参数,可以为每一行调用一个 NSIS 函数。

或者你可以自己解析:

Function nsExecLine
Pop $0
DetailPrint Line|$0|
; FileWrite ...
FunctionEnd  



!include LogicLib.nsh
nsExec::ExecToStack 'ping -n 2 localhost'
Pop $0
${If} $0 != "error"
    Pop $0
    StrCpy $1 -1
    StrCpy $3 "" ; \r \n merge
    more:
        IntOp $1 $1 + 1
        StrCpy $2 $0 1 $1
        StrCmp $2 "" done ; Can also be printlast if desired
        StrCmp $2 "$\n" +2
        StrCmp $2 "$\r" +1 more
        StrCpy $2 $0 $1
        StrCpy $4 $0 1 $1
        StrCmp $3 "" +2
        StrCmp $3 $4 0 more
        StrCpy $3 $4
        IntOp $1 $1 + 1
    ;printlast:
        StrCpy $0 $0 "" $1
        Push $0
        Push $3
        Push $2
        Call nsExecLine
        Pop $3
        Pop $0
        StrCpy $1 -1
        StrCmp $0 "" +1 more
    done:
${EndIf}

...或者作为一个小技巧,使用 ExecToLog:

!include LogicLib.nsh
!include WinMessages.nsh
!ifndef LVM_GETITEM
!ifndef LVM_FIRST
!define LVM_FIRST 0x00001000
!endif
!define /math LVM_GETITEMCOUNT ${LVM_FIRST} +  4
!ifndef NSIS_UNICODE
!define /math LVM_GETITEM ${LVM_FIRST} +  5
!else
!define /math LVM_GETITEM ${LVM_FIRST} + 75
!endif
!endif
FindWindow $9 "#32770" "" $HWNDPARENT
GetDlgItem $9 $9 0x3F8
SendMessage $9 ${LVM_GETITEMCOUNT} 0 0 $7
nsExec::ExecToLog 'ping -n 2 localhost'
Pop $0
${If} $0 != "error"
    !define MAXEXECLINE 5000
    System::Call '*(i,i,i,i,i,i,i,i,i,&t${MAXEXECLINE})i.r6'
    IntOp $8 $6 + 36
    System::Call '*$6(i,i,i,i,i,ir8,i${MAXEXECLINE},i,i)'
    SendMessage $9 ${LVM_GETITEMCOUNT} 0 0 $8
    ${DoWhile} $7 < $8
        Push $6
        Push $7
        Push $8
        Push $9
        System::Call '*$6(i1,i$7,i0)'
        SendMessage $9 ${LVM_GETITEM} 0 $6
        System::Call '*$6(i,i,i,i,i,t.r7)' ; (i,i,i,i,i,i,i,i,i,&t${MAXEXECLINE} .r7)'
        Push $7
        Call nsExecLine ; nsExecLine should not DetailPrint in this case...
        Pop $9
        Pop $8
        Pop $7
        Pop $6
        IntOp $7 $7 + 1
    ${Loop}
    System::Free $6
${EndIf}

【讨论】:

  • 我希望我能理解这些东西:/ 我会尝试修改第一个选项。谢谢。如果有效,将标记为正确
猜你喜欢
  • 1970-01-01
  • 2018-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 2018-04-21
相关资源
最近更新 更多