【发布时间】:2020-04-26 01:50:11
【问题描述】:
我在我的 nsis 卸载程序中编写了 SetSilent,但是当我从 cmd 调用它时,它会在新的 cmd 窗口中打开。我需要在我当前的 cmd 中运行卸载。你能帮帮我吗?
【问题讨论】:
-
我们需要更多信息。 NSIS 不是控制台应用程序,不会自行打开另一个控制台窗口。请发布一些代码。
标签: nsis silent uninstallation
我在我的 nsis 卸载程序中编写了 SetSilent,但是当我从 cmd 调用它时,它会在新的 cmd 窗口中打开。我需要在我当前的 cmd 中运行卸载。你能帮帮我吗?
【问题讨论】:
标签: nsis silent uninstallation
为此,我更喜欢将 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
【讨论】: