NSIS Uninstall Silent Mode запускается в текущем cmd - PullRequest
0 голосов
/ 08 января 2020

Я пишу SetSilent в моем деинсталляторе nsis, но когда я вызываю его из cmd, он открывается в новом окне cmd. Мне нужно запустить удаление в моем текущем cmd. Вы можете мне помочь?

1 Ответ

0 голосов
/ 13 января 2020

Я предпочитаю создавать NSIS как консольную программу для этой цели, однако можно разрешить программе GUI писать в существующее окно консоли. Недостаток этого метода заключается в том, что курсор ввода не перемещается вместе с выводом, поэтому пользователь, вероятно, захочет ввести cls после завершения установки, и вам придется уведомить их об этом факте. Для дополнительной поддержки я также добавил функцию DetectConsole для автоматического определения, был ли NSIS вызван из командной строки, но вам нужно будет включить этот заголовок для GetProcessInfo: https://nsis.sourceforge.io/Get_process_info

Но в любом случае это возможно с чем-то вроде ниже. Вы можете обернуть ваши DetailPrint в макрос, который также выполняет StdOutPrint, и использовать nsExe c :: ExecToStack: https://nsis.sourceforge.io/NsExec_plug-in и StdOutPrint содержимое стека (хотя вы, вероятно, захотите использовать NSIS long строки строк для получения более подробного вывода).

Если вы хотите использовать параметр / S для открытия нового командного окна при необходимости, даже если оно не вызывается из командной строки (шумная пауза), раскомментируйте 4 строки с "; $ {OrIf} $ {Silent}" и "; SetSilent silent"

!include LogicLib.nsh
!include GetProcessInfo.nsh
Var /GLOBAL StdOutHandle
Var /GLOBAL CommandLine

Function ${UN}AttachConsole  # Reuse or create a command prompt window if command line install
    Push $0
    Push $1
    StrCpy $StdOutHandle ""
    ${If} $CommandLine == "yes"
    ;${OrIf} ${Silent}
        System::Call 'kernel32::GetStdHandle(i -11)i.r0'
        System::Call 'kernel32::AttachConsole(i -1)i.r1'
        ${If} $0 = 0
        ${OrIf} $1 = 0
            System::Call 'kernel32::AllocConsole()'
            System::Call 'kernel32::GetStdHandle(i -11)i.r0'
            StrCpy $StdOutHandle $0
            FileWrite $StdOutHandle "\r\n"
        ${EndIf}
    ${EndIf}
    Pop $1
    Pop $0
FunctionEnd

!macro StdOutPrint OutputText
    ${If} $CommandLine == "yes"
    ;${OrIf} ${Silent}
        FileWrite $StdOutHandle `${OutputText} \r\n`
    ${EndIf}
!macroend
!define StdOutPrint '!insertmacro StdOutPrint'

Function ${UN}DetectConsole  # Check if run from a command line (including some known cmd.exe replacements)
    Push $0
    Push $1
    Push $2
    Push $3
    Push $4
    Push $5
    ${GetProcessInfo} 0 $0 $1 $2 $3 $4  # $0=pid $1=parent_pid $2=priority $3=name $4=fullname
    ${GetProcessInfo} $1 $0 $1 $2 $3 $5
    ${If}   $3 == "wsmprovhost.exe"     # Remote PowerShell [stdout OK, but no stdin]
    ${OrIf} $3 == "powershell.exe"      # Local PowerShell
    ${OrIf} $3 == "cmd.exe"             # Command Prompt
    ${OrIf} $3 == "tcc.exe"             # Take Command
    ${OrIf} $3 == "4nt.exe"             # 4NT
    ${OrIf} $3 == "console2.exe"        # Console2
    ${OrIf} $3 == "conemu.exe"          # ConEmu
    ${OrIf} $3 == "conemu64.exe"        # ConEmu x64
    ${OrIf} $3 == "clink_x86.exe"       # clink
    ${OrIf} $3 == "clink_x64.exe"       # clink x64
    ${OrIf} $3 == "FireCMD.exe"         # FireCMD
    ${OrIf} $3 == "far.exe"             # Far Manager
    ${OrIf} $3 == "mintty.exe"          # Cygwin/Git
    ${OrIf} $3 == "Cmder.exe"           # Cmder
    ${OrIf} $3 == "PowerCmd.exe"        # PowerCmd
        ;SetSilent silent
        StrCpy $CommandLine "yes"
    ${EndIf}
    Pop $5
    Pop $4
    Pop $3
    Pop $2
    Pop $1
    Pop $0
FunctionEnd

Function .onInit
    Call DetectConsole
    ${If} $CommandLine == "yes"
    ;${OrIf} ${Silent}
        Call AttachConsole
        ${StdOutPrint} "Hello, world!"
    ${EndIf}
FunctionEnd
...