Archive: Post installer-build events?


Post installer-build events?
I want to execute a signing tool after the installer has been built, and I want to do it within the script.

Right now I have:

!system 'Signing\SignMe.exe "Releases\installer.exe"'

at the end of the NSI file, but this signs the file before it has been really created.

Is there a way to sign the installer after it has been made? Also, how would I be able to reference the OutFile location, without hardcoding the output path?


Why don't you just make a build.bat file to build your installer?

"C:\Program Files\NSIS\makensis.exe" "My Installer.nsi"
Signing\SignMe.exe "Releases\installer.exe"


If you put the batch file in the same folder as the .nsi file it should all work.

Well, normally I would do that but I'm running a number of post installer-build events and I want them to all use the OutFile variable, and if that's not possible I'd still like them all in the same place.

Is it impossible to run a command within the nsi file after the installer has been built?


I don't know of a way to do a post build event from within an NSIS script.

You could pass in the OutFile to the build batch file and pass it along to makensis. Then you can use the variable for whatever post events you want:

@echo off

IF "%~1"=="" (
echo Usage: build OutFile.exe
pause
exit
) ELSE (SET OutFile=%~1)

"C:\Progam Files\NSIS\makensis.exe" "My Installer.nsi" "/XOutFile %OutFile%"
NSIS\makensis.exe "My Installer.nsi" "/XOutFile %OutFile%"
Signing\SignMe.exe "Releases\%OutFile%"
xcopy "Releases\%OutFile%" \\MyServer\Backup
...
pause

SignMe.exe should be used same way as an external packer,

http://nsis.sourceforge.net/Docs/Chapter5.html#5.1.10


You can use !execute or !system, but they both wait for the called program to finish before they let makensis finish.

If you !execute a program that will start another one (and not wait for it to finish), you could have your second program wait for makensis to complete, and then do the commands you are trying to do.

Rather round-about, but possible.

Don


Here's a vbscript that can wait for makensis to exit, and then call SignMe.exe. Put this into a file called SignNsi.vbs, in the same folder as your nsi script:

Set sh=Wscript.CreateObject("WScript.Shell")
Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

ExeName = Wscript.Arguments(0)
WQL = "Select Name from Win32_Process Where Name='makensis.exe'"

Do While MakeNsisActive
Wscript.Sleep 250
Loop

sh.Run "Signing\SignMe.exe Releases\" & ExeName

Function MakeNsisActive
MakeNsisActive = CBool(Wmi.ExecQuery(WQL).Count > 0)
End Function


Here's the code that would go at the end of the NSIS script. Note that I have used a define called FILENAME for the output file, and used your relative path Releases:
!define ExeName "Releases\${FILENAME}"
!tempfile FILE
!appendfile "${FILE}.vbs" 'set s=CreateObject("WScript.Shell")$\n'
!appendfile "${FILE}.vbs" 's.run "wscript SignNsi.vbs ${ExeName}",0,False$\n'
# execute (and wait for) the two-line script above
!execute "wscript ${FILE}.vbs"
# delete the vbs and tempfile now
!delfile "${FILE}.vbs"
!delfile "${FILE}"

Don

you dont need the first script(edit: last in your post, but the first executed :) ), something like

!execute '$%COMSPEC% /c start wscript.exe SignNsi.vbs ${ExeName}'

should probably do it


During the testing I did before I posted, it looked like makensis waited for the %COMSPEC% program to complete before it creates the final installer (nsi executable). The first script I call terminates (after starting the second one) and thus the installer gets created.

I'll repeat the testing to confirm it.

Don


@Anders: I see, you combined COMSPEC and Start. I agree with you, it works and that simplifies the code at the end of the nsi script.

I notice that I have the path Release coded in the vbscript and also added it in the !define ExeName before calling the vbscript. One of them should be removed.

Don


Red Wine: That signs the installer before it has been fully created, thus the signature is valid for an incomplete installer, but invalid for the entirely complete installer.

Demiller9: Your method worked, though I ended up writing a small c# console program instead of vbscript, mainly because I wouldn't be able to maintain the script. But your idea of waiting for makensis to exit made the difference.

I still have one problem though: I have

OutFile "Releases\setup.exe"


defined in the script. Is there a way to reference the OutFile variable? Namely, to pass it as commandline argument. Right now I have to redefine the output location when I sign the file:

!system '"Signing\SignMe.exe" "Releases\setup.exe" /w'


I've tried $EXEPATH, but that seems to be an install-time variable.

you could use a define.

Maybe someone should add a feature request for something like !systemEOF or something that executes after makensis is done writing to the installer


I requested for something similar, !macro CompileDone or something it was. I think the answer currently is to use a batch file.

Stu