I use option 1. The updater process gets updated very rarely these days. It uses an XML file containing the details of where to get the files from (currently supports SVN, working on adding NuGet support) and where to put them. It also specifies which ones are services and which ones are websites and specifies the name of the service to use for each project.
The process polls the source, if there is a new version available it copies it down to a fresh version numbered directory and then updates the service. It also keeps 5 copies of each update making it easy to roll-back if there is a problem.
Here's the core piece of code for the updater which stops the existing service, copies the files over, and then restarts it.
if (isService)
{
log.Debug("Stopping service " + project.ServiceName);
var service = GetService(project);
if (service != null &&
service.Status != System.ServiceProcess.ServiceControllerStatus.Stopped && service.Status != System.ServiceProcess.ServiceControllerStatus.StopPending)
{
service.Stop();
}
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped, new TimeSpan(0, 1, 0));
if (service.Status == System.ServiceProcess.ServiceControllerStatus.Stopped)
log.Debug("Service stopped");
else
log.Error("ERROR: Expected Stopped by Service is " + service.Status);
}
log.Debug("Copying files over");
CopyFolder(checkoutDirectory, destinationDirectory);
if (isService)
{
log.Debug("Starting service");
var service = GetService(project);
// Currently it doesn't create services, you need to do that manually
if (service != null)
{
service.Start();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running, new TimeSpan(0, 1, 0));
if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)
log.Debug("Service running");
else
log.Error("Service " + service.Status);
}
}