Visual Studio has a "Setup and Deployment" project, that is mostly easy to set up with a bunch of clicks.
If you want to customize the installer (with options for the user), you need to write little programs to do each custom operation.
The scripts can be written as *.exe or *.dll files, which need to be compiled. That seems a bit overkill.
The scripts can also be written as VBS (Visual Basic Scripting) language. For someone like me, I don't want to know about VBS, but that's the only other option you have. VBS is not the same as VB, but it is similar. In addition, some of the default assemblies you have access to in VBS from the command line are not available from the Setup Project.
To test out a VBS script, you run the 'cscript' command from the command line, or double click it.
Here's a VBS script that opens a firewall. You add the script to the Custom Action -> Commit, and change the CustomActionData property to
[TARGETDIR]. There a bunch of variables you can pass in CustomActionData, but I've yet to find a complete list of them online.
You can make it conditional by adding something to the UserInterface (say Checkboxes (A)), name the property name of that checkbox, and then use that in a conditional for the custom action. Sorry that's vague, but should give me some hints when I actually need to implement it.
Dim target
'msgbox "start"
'msgbox Session.Property("CustomActionData")
target = Session.Property("CustomActionData")
'msgbox target
Set objFirewall = CreateObject("HNetCfg.FwMgr")
Set objPolicy = objFirewall.LocalPolicy.CurrentProfile
filename = target & "cog-trk-db-service.exe"
'msgbox filename
Set objApplication = CreateObject("HNetCfg.FwAuthorizedApplication")
objApplication.Name = "cog-trk-db-service"
objApplication.IPVersion = 2
objApplication.ProcessImageFileName = filename
objApplication.RemoteAddresses = "*"
objApplication.Scope = 0
objApplication.Enabled = True
Set colApplications = objPolicy.AuthorizedApplications
colApplications.Add(objApplication)
msgbox "Firewall exception created for " & filename
'msgbox "stop"