$ git clone http://tcclient.ion.nu/tc_client.git
commit e3ad693aafaadd8feca9989737502a4d24ae2656
Author: Alicia <...>
Date:   Tue Jun 9 17:14:52 2015 +0200

    tc_client-gtk: made the options for notifications and youtube videos work for windows.

diff --git a/ChangeLog b/ChangeLog
index ecde538..3444de8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,7 @@ Fixed the /forgive command (by name) which would previously fail unless the targ
 modbot: fixed finding the duration of videos longer than 59 minutes (conversion from hh:mm:ss format to seconds)
 tc_client-gtk: redesigned the startup window to better support frequenting multiple channels.
 tc_client-gtk and camviewer: added compatibility code to build on windows (for now the tc_client core still needs to be built with cygwin for windows)
+tc_client-gtk: made the options for notifications and youtube videos work for windows.
 0.32:
 Added an 'install' make target, adjusted utilities to run tc_client from PATH unless they were run from the build directory (i.e. './<executable>')
 Provide feedback on the /ban command.
diff --git a/utilities/gtk/camviewer.c b/utilities/gtk/camviewer.c
index 037f41a..5ee6e56 100644
--- a/utilities/gtk/camviewer.c
+++ b/utilities/gtk/camviewer.c
@@ -233,42 +233,58 @@ gboolean handledata(GIOChannel* iochannel, GIOCondition condition, gpointer data
     if(space[-1]==':')
     {
 // TODO: handle /msg (PMs)
-#ifndef _WIN32 // TODO: port sound and youtube command code to windows
-      if(config_get_bool("soundradio_cmd") && !fork())
+      if(config_get_bool("soundradio_cmd"))
       {
-        execlp("sh", "sh", "-c", config_get_str("soundcmd"), (char*)0);
-        _exit(0);
+#ifdef _WIN32
+        char* cmd=strdup(config_get_str("soundcmd"));
+        w32_runcmd(cmd);
+        free(cmd);
+#else
+        if(!fork())
+        {
+          execlp("sh", "sh", "-c", config_get_str("soundcmd"), (char*)0);
+          _exit(0);
+        }
+#endif
       }
-      if(!strncmp(space, " /mbs youTube ", 14) && config_get_bool("youtuberadio_cmd") && !fork())
+      if(!strncmp(space, " /mbs youTube ", 14) && config_get_bool("youtuberadio_cmd"))
       {
+#ifndef _WIN32
+        if(!fork())
+#endif
+        {
 // TODO: store the PID and make sure it's dead before starting a new video? and upon /mbc?
 // TODO: only play videos from mods?
-        char* id=&space[14];
-        char* offset=strchr(id, ' ');
-        if(!offset){_exit(1);}
-        offset[0]=0;
-        offset=&offset[1];
-        char* end=strchr(offset, ' '); // Ignore any additional arguments after the offset (the modbot utility includes the video title here)
-        if(end){end[0]=0;}
-        // Handle format string
-        const char* fmt=config_get_str("youtubecmd");
-        int len=strlen(fmt)+1;
-        len+=strcount(fmt, "%i")*(strlen(id)-2);
-        len+=strcount(fmt, "%t")*(strlen(id)-2);
-        char cmd[len];
-        cmd[0]=0;
-        while(fmt[0])
-        {
-          if(!strncmp(fmt, "%i", 2)){strcat(cmd, id); fmt=&fmt[2]; continue;}
-          if(!strncmp(fmt, "%t", 2)){strcat(cmd, offset); fmt=&fmt[2]; continue;}
-          for(len=0; fmt[len] && strncmp(&fmt[len], "%i", 2) && strncmp(&fmt[len], "%t", 2); ++len);
-          strncat(cmd, fmt, len);
-          fmt=&fmt[len];
+          char* id=&space[14];
+          char* offset=strchr(id, ' ');
+          if(!offset){_exit(1);}
+          offset[0]=0;
+          offset=&offset[1];
+          char* end=strchr(offset, ' '); // Ignore any additional arguments after the offset (the modbot utility includes the video title here)
+          if(end){end[0]=0;}
+          // Handle format string
+          const char* fmt=config_get_str("youtubecmd");
+          int len=strlen(fmt)+1;
+          len+=strcount(fmt, "%i")*(strlen(id)-2);
+          len+=strcount(fmt, "%t")*(strlen(id)-2);
+          char cmd[len];
+          cmd[0]=0;
+          while(fmt[0])
+          {
+            if(!strncmp(fmt, "%i", 2)){strcat(cmd, id); fmt=&fmt[2]; continue;}
+            if(!strncmp(fmt, "%t", 2)){strcat(cmd, offset); fmt=&fmt[2]; continue;}
+            for(len=0; fmt[len] && strncmp(&fmt[len], "%i", 2) && strncmp(&fmt[len], "%t", 2); ++len);
+            strncat(cmd, fmt, len);
+            fmt=&fmt[len];
+          }
+#ifdef _WIN32
+          w32_runcmd(cmd);
+#else
+          execlp("sh", "sh", "-c", cmd, (char*)0);
+          _exit(0);
+#endif
         }
-        execlp("sh", "sh", "-c", cmd, (char*)0);
-        _exit(0);
       }
-#endif
     }
 // TODO: handle logging PMs
     if(config_get_bool("enable_logging")){logger_write(buf, channel, 0);}
diff --git a/utilities/gtk/compat.h b/utilities/gtk/compat.h
index cd61c08..9028da5 100644
--- a/utilities/gtk/compat.h
+++ b/utilities/gtk/compat.h
@@ -17,6 +17,12 @@
 #ifdef _WIN32
 #include <wtypes.h>
 extern SECURITY_ATTRIBUTES sa;
+#define w32_runcmd(cmd) \
+  { \
+    char* arg=strchr(cmd,''); \
+    if(arg){arg[0]=0; arg=&arg[1];} \
+    ShellExecute(0, "open", cmd, arg, 0, SW_SHOWNORMAL); \
+  }
 #endif
 #if GTK_MAJOR_VERSION<3
   #define GTK_ORIENTATION_HORIZONTAL 0