diff --git a/src/signal_handler.c b/src/signal_handler.c
index 7997a35f5ff6bcd8de83a7f1114c1f8c2aa0ae40..4fde1de94615cda3324be1659e23dd05e4be6955 100644
--- a/src/signal_handler.c
+++ b/src/signal_handler.c
@@ -2814,11 +2814,11 @@ void f_create_process(INT32 args)
     HANDLE t1 = DO_NOT_WARN(INVALID_HANDLE_VALUE);
     HANDLE t2 = DO_NOT_WARN(INVALID_HANDLE_VALUE);
     HANDLE t3 = DO_NOT_WARN(INVALID_HANDLE_VALUE);
-    STARTUPINFO info;
+    STARTUPINFOW info;
     PROCESS_INFORMATION proc;
     int ret,err;
-    TCHAR *filename=NULL, *command_line=NULL, *dir=NULL;
-    void *env=NULL;
+    WCHAR *filename=NULL, *command_line=NULL, *dir=NULL;
+    WCHAR *env=NULL;
 
     /* Quote command to allow all characters (if possible) */
     /* Damn! NT doesn't have quoting! The below code attempts to
@@ -2910,7 +2910,8 @@ void f_create_process(INT32 args)
        *       operations on it.
        */
 
-      command_line=(TCHAR *)buf.s.str;
+      command_line = pike_dwim_utf8_to_utf16(buf.s.str);
+      toss_buffer(&buf);
     }
 
     /* FIXME: Ought to set filename properly.
@@ -2918,8 +2919,8 @@ void f_create_process(INT32 args)
 
     memset(&info,0,sizeof(info));
     info.cb=sizeof(info);
-    
-    GetStartupInfo(&info);
+
+    GetStartupInfoW(&info);
 
     /* Protect inherit status for handles */
     LOCK_IMUTEX(&handle_protection_mutex);
@@ -2938,7 +2939,7 @@ void f_create_process(INT32 args)
       {
 	if(TYPEOF(*tmp) == T_STRING)
 	{
-	  dir=(TCHAR *)STR0(tmp->u.string);
+	  dir = pike_dwim_utf8_to_utf16(STR0(tmp->u.string));
 	  /* fprintf(stderr,"DIR: %s\n",STR0(tmp->u.string)); */
 	}
       }
@@ -2987,8 +2988,13 @@ void f_create_process(INT32 args)
 	    f_aggregate(ptr+1);
 	    push_string(make_shared_binary_string("\0",1));
 	    o_multiply();
-	    /* FIXME: Wide strings? */
-	    env=(void *)Pike_sp[-1].u.string->str;
+
+	    /* NB: The environment string contains lots of NUL characters,
+	     *     so we must use the low-level variant here.
+	     */
+	    env = low_dwim_utf8_to_utf16(Pike_sp[-1].u.string->str,
+					 Pike_sp[-1].u.string->str->len);
+	    pop_stack();
 	  }
 	}
 
@@ -2998,26 +3004,31 @@ void f_create_process(INT32 args)
     THREADS_ALLOW_UID();
 
 
-    SetHandleInformation(info.hStdInput, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
-    SetHandleInformation(info.hStdOutput, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
-    SetHandleInformation(info.hStdError, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
-    ret=CreateProcess(filename,
-		      command_line,
-		      NULL,  /* process security attribute */
-		      NULL,  /* thread security attribute */
-		      1,     /* inherithandles */
-		      0,     /* create flags */
-		      env,  /* environment */
-		      dir,   /* current dir */
-		      &info,
-		      &proc);
+    SetHandleInformation(info.hStdInput, HANDLE_FLAG_INHERIT,
+			 HANDLE_FLAG_INHERIT);
+    SetHandleInformation(info.hStdOutput, HANDLE_FLAG_INHERIT,
+			 HANDLE_FLAG_INHERIT);
+    SetHandleInformation(info.hStdError, HANDLE_FLAG_INHERIT,
+			 HANDLE_FLAG_INHERIT);
+    ret = CreateProcessW(filename,
+			 command_line,
+			 NULL,  /* process security attribute */
+			 NULL,  /* thread security attribute */
+			 1,     /* inherithandles */
+			 CREATE_UNICODE_ENVIRONMENT,     /* create flags */
+			 env,  /* environment */
+			 dir,   /* current dir */
+			 &info,
+			 &proc);
     err=GetLastError();
     
     THREADS_DISALLOW_UID();
 
     UNLOCK_IMUTEX(&handle_protection_mutex);
 
-    if(env) pop_stack();
+    if(env) free(env);
+    if(dir) free(dir);
+    if(filename) free(filename);
     if(command_line) free(command_line);
 #if 1
     if(t1 != DO_NOT_WARN(INVALID_HANDLE_VALUE)) CloseHandle(t1);