diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java
index 89a9d48eb174a1bceb92ce439c69932d3cc35831..9193c8731413a22c1cefef897ad58dc1c9209ad5 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java
@@ -160,8 +160,7 @@ public class ConfigServiceHandler extends FormHandler {
      *  @since 0.8.13
      */
     synchronized static void registerSignalHandler(RouterContext ctx) {
-        if (ctx.hasWrapper() && _wrapperListener == null &&
-            !SystemVersion.isWindows()) {
+        if (ctx.hasWrapper() && _wrapperListener == null) {
             String wv = System.getProperty("wrapper.version");
             if (wv != null && VersionComparator.comp(wv, LISTENER_AVAILABLE) >= 0) {
                 try {
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/WrapperListener.java b/apps/routerconsole/java/src/net/i2p/router/web/WrapperListener.java
index 8562398a782bc363d7906d783c0a7fe3054b7dfe..e2945da8a3facb5245065778b3e542f3ea7af7d1 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/WrapperListener.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/WrapperListener.java
@@ -3,9 +3,11 @@ package net.i2p.router.web;
 import net.i2p.router.Router;
 import net.i2p.router.RouterContext;
 import net.i2p.util.Log;
+import net.i2p.util.SystemVersion;
 
 import org.tanukisoftware.wrapper.WrapperManager;
 import org.tanukisoftware.wrapper.event.WrapperControlEvent;
+import org.tanukisoftware.wrapper.event.WrapperServiceControlEvent;
 import org.tanukisoftware.wrapper.event.WrapperEvent;
 import org.tanukisoftware.wrapper.event.WrapperEventListener;
 
@@ -28,7 +30,9 @@ class WrapperListener {
      */
     public WrapperListener(RouterContext ctx) {
         _listener = new SignalHandler(ctx);
-        long mask = WrapperEventListener.EVENT_FLAG_CONTROL;
+        long mask = SystemVersion.isWindows() ? WrapperEventListener.EVENT_FLAG_SERVICE :
+                                                WrapperEventListener.EVENT_FLAG_CONTROL;
+
         WrapperManager.addWrapperEventListener(_listener, mask);
     }
 
@@ -55,10 +59,37 @@ class WrapperListener {
         }
 
         public void fired(WrapperEvent event) {
-            if (!(event instanceof WrapperControlEvent))
+            Log log = _ctxt.logManager().getLog(ConfigServiceHandler.class);
+            if (SystemVersion.isWindows() && (event instanceof WrapperServiceControlEvent)) {
+                WrapperServiceControlEvent wcse = (WrapperServiceControlEvent) event;
+                int code = wcse.getServiceControlCode();
+                switch (code) {
+                  case WrapperManager.SERVICE_CONTROL_CODE_STOP:       // 1
+                  case WrapperManager.SERVICE_CONTROL_CODE_SHUTDOWN:   // 5
+                    log.log(Log.CRIT, "Hard shutdown initiated by Windows service control: " + code);
+                    // JVM will call ShutdownHook if we don't do it ourselves
+                    ConfigServiceHandler.registerWrapperNotifier(_ctxt, Router.EXIT_HARD, false);
+                    _ctxt.router().shutdown(Router.EXIT_HARD);
+                    break;
+
+                  // TODO Power suspend/resume?
+                  // Warning, definitions not available in 3.2.0, use integers
+                  // Tanuki doesn't usually mark things with @since, sadly
+                  // case 35xx // WrapperManager.SERVICE_CONTROL_POWEREVENT_ ...
+                  //  break;
+
+                  default:
+                    if (log.shouldWarn())
+                        log.warn("Unhandled control event code: " + code);
+                    break;
+                }
+                return;
+            } else if (!(event instanceof WrapperControlEvent)) {
+                if (log.shouldWarn())
+                    log.warn("Got unhandled event: " + event);
                 return;
+            }
             WrapperControlEvent wce = (WrapperControlEvent) event;
-            Log log = _ctxt.logManager().getLog(ConfigServiceHandler.class);
             if (log.shouldLog(Log.WARN))
                 log.warn("Got signal: " + wce.getControlEventName());
             int sig = wce.getControlEvent();