NSIS - printing to prompt during command line install
Asked Answered
V

2

8

I'm making installers for windows using NSIS and have a number of custom install options that the user can specify using the command line, for example:

installer.exe /IDPATH=c:\Program Files\Adobe\Adobe InDesign CS5 /S

What I want to do is show these options to the person installing. I can easily enough parse the /? or /help parameters with ${GetParameters} and ${GetOptions}, but how do I do the actual printing to the command prompt?

Versicular answered 23/6, 2010 at 15:48 Comment(0)
I
10

NSIS is a GUI program and does not really have the ability to write to stdout.

On XP and later you can do this with the system plugin:

System::Call 'kernel32::GetStdHandle(i -11)i.r0' 
System::Call 'kernel32::AttachConsole(i -1)' 
FileWrite $0 "hello" 

On < XP, there is no AttachConsole and you need to call AllocConsole on those systems (Will probably open a new console window)

Edit: You could open a new console if the parent process does not have one already with

!include LogicLib.nsh
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' 
${EndIf}
FileWrite $0 "hello$\n" 

But it does not really make any sense as far as /? handling goes, you might as well open a message box when there is no console

!include LogicLib.nsh
StrCpy $9 "USAGE: Hello world!!" ;the message
System::Call 'kernel32::GetStdHandle(i -11)i.r0' ;try to get stdout
System::Call 'kernel32::AttachConsole(i -1)i.r1' ;attach to parent console
${If} $0 <> 0
${AndIf} $1 <> 0
 FileWrite $0 "$9$\n" 
${Else}
 MessageBox mb_iconinformation $9
${EndIf}
Incontinent answered 23/6, 2010 at 19:34 Comment(6)
It would appear that simply pasting this code into the .oninit does nothing visible on an XP machine. Do I need to set anything up such as the values of i and r0? I also dont quite understand what each of these lines do. I would presume that the first line gets the handle of the current console, the second line links $0 to that console so that subsequent writes to that virtual file will end up in the console. Is this accurate? I also tried the longer code samples found on winamp forums when googling for nsis kernel32::attachconsole, but they seem to have the same problem.Versicular
After even more googling to random pages I think I've figured out that all the 'i' simply denotes that the following is an integer. As you can tell my knowledge of the windows api is very basic.Versicular
You need to run the program from within a open console (cmd.exe)Incontinent
That is what I am doing. Using AllocConsole instead of AttachConsole seems to do nothing either.Versicular
Worked for me. Except that it doesn't close. I am guessing there is a fileClose type function to go with FileWriteHellman
@Jon: There is a FreeConsole function if you want to force a disconnect from the console...Incontinent
G
1
!include LogicLib.nsh
StrCpy $9 "USAGE: Hello world!!" ;the message
System::Call 'kernel32::AttachConsole(i -1)i.r0' ;attach to parent console
${If} $0 != 0
 System::Call 'kernel32::GetStdHandle(i -11)i.r0' ;console attached -- get stdout
 FileWrite $0 "$9$\n" 
${Else}
 ;no console to attach -- show gui message
 MessageBox mb_iconinformation $9
${EndIf}

First attach console then get std handle. Before attach handles may (often will) be invalid.

Gingili answered 19/3, 2019 at 14:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.