Skip to content

Instantly share code, notes, and snippets.

@chilversc
Last active February 5, 2016 19:49
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chilversc/8f7adbc09aa92f53e0ae to your computer and use it in GitHub Desktop.
Save chilversc/8f7adbc09aa92f53e0ae to your computer and use it in GitHub Desktop.
Automatically reload topshelf service after build
using System;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;
class Program
{
const string exe = "Server.exe";
const string config = exe + ".config";
const int QuietPeriod = 1000;
static int processId;
static bool shutdown = false;
static bool reload = false;
static Timer timer;
static FileSystemWatcher watcher;
static int Main (string[] args)
{
Console.CancelKeyPress += (sender, evt) => {
if (evt.SpecialKey == ConsoleSpecialKey.ControlC) {
// in case ^C is pressed while a defered reload is signaled
shutdown = true;
}
};
processId = GetProcessId ();
WatchForChanges ();
int result = 0;
do {
reload = false;
result = Run (args);
} while (reload && !shutdown);
return result;
}
static void WatchForChanges ()
{
timer = new Timer (Restart);
watcher = new FileSystemWatcher (Environment.CurrentDirectory);
watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.Size;
watcher.Changed += TriggerRestart;
watcher.Created += TriggerRestart;
watcher.Deleted += TriggerRestart;
watcher.Renamed += TriggerRestart;
watcher.EnableRaisingEvents = true;
}
static void TriggerRestart (object sender, EventArgs args)
{
timer.Change (QuietPeriod, Timeout.Infinite);
}
static void Restart (object state)
{
reload = true;
GenerateConsoleCtrlEvent (ConsoleCtrlEvent.CTRL_C, processId);
}
static int Run (string[] args)
{
var setup = new AppDomainSetup {
ShadowCopyFiles = bool.TrueString,
ApplicationBase = Environment.CurrentDirectory,
ConfigurationFile = config,
};
var domain = AppDomain.CreateDomain ("Service", null, setup);
var result = domain.ExecuteAssembly (exe, args);
AppDomain.Unload (domain);
if (reload) {
Console.ForegroundColor = ConsoleColor.Yellow;
Console.BackgroundColor = ConsoleColor.DarkMagenta;
Console.Write("--- RESTARTING ---");
Console.ResetColor();
Console.WriteLine();
}
return result;
}
static int GetProcessId ()
{
using (var process = Process.GetCurrentProcess()) {
return process.Id;
}
}
[DllImport("kernel32.dll", SetLastError=true)]
static extern bool GenerateConsoleCtrlEvent(ConsoleCtrlEvent sigevent, int dwProcessGroupId);
public enum ConsoleCtrlEvent
{
CTRL_C = 0,
CTRL_BREAK = 1,
CTRL_CLOSE = 2,
CTRL_LOGOFF = 5,
CTRL_SHUTDOWN = 6
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment