- NSIS Discussion
- Post installer-build events?
Archive: Post installer-build events?
vbguy
21st August 2007 02:46 UTC
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?
michaelcsikos
21st August 2007 03:28 UTC
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.
vbguy
21st August 2007 03:54 UTC
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?
michaelcsikos
21st August 2007 04:36 UTC
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
Red Wine
21st August 2007 05:31 UTC
SignMe.exe should be used same way as an external packer,
http://nsis.sourceforge.net/Docs/Chapter5.html#5.1.10
demiller9
21st August 2007 07:43 UTC
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
demiller9
21st August 2007 08:25 UTC
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
Anders
21st August 2007 15:10 UTC
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
demiller9
21st August 2007 17:02 UTC
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
demiller9
21st August 2007 17:28 UTC
@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
vbguy
31st August 2007 08:24 UTC
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.
Anders
31st August 2007 15:56 UTC
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
Afrow UK
31st August 2007 16:42 UTC
I requested for something similar, !macro CompileDone or something it was. I think the answer currently is to use a batch file.
Stu