diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp
index d0d44dbca2b32dcda99008a258b4e2329aa7f0b9..2dde6762d6c0bbf30641a104a2572261307504ec 100644
--- a/Common/GmshMessage.cpp
+++ b/Common/GmshMessage.cpp
@@ -124,12 +124,15 @@ void Msg::Init(int argc, char **argv)
     char *tmp = getenv("PYTHONPATH");
     if(tmp){
       path = tmp;
+#if defined(WIN32)
+      path += ";" + split[0];
+#else
       path += ":" + split[0];
+#endif
     }
     else
       path = split[0];
-    setenv("PYTHONPATH", path.c_str(), 1);
-    printf("pythonpath = %s\n", path.c_str());
+    SetEnvironmentVar("PYTHONPATH", path.c_str());
   }
 
   InitializeOnelab("Gmsh");
diff --git a/Common/OS.cpp b/Common/OS.cpp
index a6f3f59a7192ba1ce099b45b562313e0c8f50431..6631d84e23b079ba54515b589fbc0b9453ba9351 100644
--- a/Common/OS.cpp
+++ b/Common/OS.cpp
@@ -53,6 +53,15 @@ const char *GetEnvironmentVar(const char *var)
 #endif
 }
 
+const void SetEnvironmentVar(const char *var, const char *val)
+{
+#if !defined(WIN32)
+  setenv(var, val, 1);
+#else
+  _putenv((std::string(var) + "=" + std::string(val)).c_str());
+#endif
+}
+
 double GetTimeInSeconds()
 {
 #if !defined(WIN32) || defined(__CYGWIN__)
@@ -197,27 +206,47 @@ int KillProcess(int pid)
 int SystemCall(const std::string &command, bool blocking)
 {
 #if defined(WIN32)
-  STARTUPINFO suInfo;
-  PROCESS_INFORMATION prInfo;
-  memset(&suInfo, 0, sizeof(suInfo));
-  suInfo.cb = sizeof(suInfo);
-  Msg::Info("Calling '%s'", command.c_str());
-  if(blocking){
-    CreateProcess(NULL, (char*)command.c_str(), NULL, NULL, FALSE,
-                  NORMAL_PRIORITY_CLASS, NULL, NULL,
-                  &suInfo, &prInfo);
-    // wait until child process exits.
-    WaitForSingleObject(prInfo.hProcess, INFINITE);
-    // close process and thread handles.
-    CloseHandle(prInfo.hProcess);
-    CloseHandle(prInfo.hThread);
+  // check if we are trying to execute a Python script
+  std::string exe, args;
+  std::string::size_type pos = command.find_first_of(" ");
+  if(pos != std::string::npos){
+    exe = command.substr(0, pos);
+    args = command.substr(pos, command.size() - pos);
+  }
+  else exe = command;
+  int s = exe.size();
+  if(s > 3 && 
+     (exe[s-3] == '.') &&
+     (exe[s-2] == 'p' || exe[s-2] == 'P') &&
+     (exe[s-1] == 'y' || exe[s-1] == 'Y')){
+    Msg::Info("Shell opening '%s' with arguments '%s'", 
+	      exe.c_str(), args.c_str());
+    ShellExecute(NULL, (char*)"open", (char*)exe.c_str(), 
+		 (char*)args.c_str(), NULL, 0);
   }
   else{
-    // DETACHED_PROCESS removes the console (useful if the program to launch is
-    // a console-mode exe)
-    CreateProcess(NULL, (char*)command.c_str(), NULL, NULL, FALSE,
-                  NORMAL_PRIORITY_CLASS|DETACHED_PROCESS, NULL, NULL,
-                  &suInfo, &prInfo);
+    STARTUPINFO suInfo;
+    PROCESS_INFORMATION prInfo;
+    memset(&suInfo, 0, sizeof(suInfo));
+    suInfo.cb = sizeof(suInfo);
+    Msg::Info("Calling '%s'", command.c_str());
+    if(blocking){
+      CreateProcess(NULL, (char*)command.c_str(), NULL, NULL, FALSE,
+		    NORMAL_PRIORITY_CLASS, NULL, NULL,
+		    &suInfo, &prInfo);
+      // wait until child process exits.
+      WaitForSingleObject(prInfo.hProcess, INFINITE);
+      // close process and thread handles.
+      CloseHandle(prInfo.hProcess);
+      CloseHandle(prInfo.hThread);
+    }
+    else{
+      // DETACHED_PROCESS removes the console (useful if the program to launch is
+      // a console-mode exe)
+      CreateProcess(NULL, (char*)command.c_str(), NULL, NULL, FALSE,
+		    NORMAL_PRIORITY_CLASS|DETACHED_PROCESS, NULL, NULL,
+		    &suInfo, &prInfo);
+    }
   }
   return 0;
 #else
diff --git a/Common/OS.h b/Common/OS.h
index bd4d39d7d348e1e7abc44517f1105a786199b310..d0b4067beb15d63e5457e8538fec9c2367f15990 100644
--- a/Common/OS.h
+++ b/Common/OS.h
@@ -9,6 +9,7 @@
 #include <string>
 
 const char *GetEnvironmentVar(const char *var);
+void SetEnvironmentVar(const char *var, const char *val);
 double GetTimeInSeconds();
 void SleepInSeconds(double s);
 void CheckResources();