【问题标题】:NSIS Uninstall Silent mode run in current cmdNSIS 卸载静默模式在当前 cmd 中运行
【发布时间】:2020-04-26 01:50:11
【问题描述】:

我在我的 nsis 卸载程序中编写了 SetSilent,但是当我从 cmd 调用它时,它会在新的 cmd 窗口中打开。我需要在我当前的 cmd 中运行卸载。你能帮帮我吗?

【问题讨论】:

  • 我们需要更多信息。 NSIS 不是控制台应用程序,不会自行打开另一个控制台窗口。请发布一些代码。

标签: nsis silent uninstallation


【解决方案1】:

为此,我更喜欢将 NSIS 构建为控制台程序,但是可以允许 GUI 程序写入现有的控制台窗口。这种方法的缺点是输入光标不会随输出移动,因此用户可能希望在安装完成后输入 cls,而您必须将这一事实通知他们。为了获得额外的荣誉,我还添加了一个 DetectConsole 函数来自动确定是否从命令行调用了 NSIS,但是您需要为 GetProcessInfo 包含此标头: https://nsis.sourceforge.io/Get_process_info

但在任何情况下,都可以使用以下内容。您可以将 DetailPrint 包装在一个也执行 StdOutPrint 的宏中,并使用 nsExec::ExecToStack : https://nsis.sourceforge.io/NsExec_plug-in 和 StdOutPrint 堆栈内容(尽管您可能希望使用 NSIS 长字符串构建来捕获更详细的输出)。

如果你想在必要时使用 /S 参数打开一个新的命令窗口,即使没有从命令行调用(嘈杂的沉默),然后用 ";${OrIf} ${Silent} 取消注释这 4 行" 和 ";SetSilent 静音"

!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

【讨论】:

    猜你喜欢
    • 2017-09-10
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    • 2016-01-11
    • 2016-06-30
    • 1970-01-01
    相关资源
    最近更新 更多