+ DWORD dwFlags = CREATE_SUSPENDED;
+
+#ifndef __WXWINCE__
+ if ( (flags & wxEXEC_MAKE_GROUP_LEADER) &&
+ (wxGetOsVersion() == wxOS_WINDOWS_NT) )
+ dwFlags |= CREATE_NEW_PROCESS_GROUP;
+
+ dwFlags |= CREATE_DEFAULT_ERROR_MODE ;
+#else
+ // we are assuming commands without spaces for now
+ wxString moduleName = command.BeforeFirst(wxT(' '));
+ wxString arguments = command.AfterFirst(wxT(' '));
+#endif
+
+ wxWxCharBuffer envBuffer;
+ bool useCwd = false;
+ if ( env )
+ {
+ useCwd = !env->cwd.empty();
+
+ // Translate environment variable map into NUL-terminated list of
+ // NUL-terminated strings.
+ if ( !env->env.empty() )
+ {
+#if wxUSE_UNICODE
+ // Environment variables can contain non-ASCII characters. We could
+ // check for it and not use this flag if everything is really ASCII
+ // only but there doesn't seem to be any reason to do it so just
+ // assume Unicode by default.
+ dwFlags |= CREATE_UNICODE_ENVIRONMENT;
+#endif // wxUSE_UNICODE
+
+ wxEnvVariableHashMap::const_iterator it;
+
+ size_t envSz = 1; // ending '\0'
+ for ( it = env->env.begin(); it != env->env.end(); ++it )
+ {
+ // Add size of env variable name and value, and '=' char and
+ // ending '\0'
+ envSz += it->first.length() + it->second.length() + 2;
+ }
+
+ envBuffer.extend(envSz);
+
+ wxChar *p = envBuffer.data();
+ for ( it = env->env.begin(); it != env->env.end(); ++it )
+ {
+ const wxString line = it->first + wxS("=") + it->second;
+
+ // Include the trailing NUL which will always terminate the
+ // buffer returned by t_str().
+ const size_t len = line.length() + 1;
+
+ wxTmemcpy(p, line.t_str(), len);
+
+ p += len;
+ }
+
+ // And another NUL to terminate the list of NUL-terminated strings.
+ *p = 0;
+ }
+ }
+
+ // Translate wxWidgets priority to Windows conventions.
+ if ( handler )
+ {
+ unsigned prio = handler->GetPriority();
+ if ( prio <= 20 )
+ dwFlags |= IDLE_PRIORITY_CLASS;
+ else if ( prio <= 40 )
+ dwFlags |= BELOW_NORMAL_PRIORITY_CLASS;
+ else if ( prio <= 60 )
+ dwFlags |= NORMAL_PRIORITY_CLASS;
+ else if ( prio <= 80 )
+ dwFlags |= ABOVE_NORMAL_PRIORITY_CLASS;
+ else if ( prio <= 99 )
+ dwFlags |= HIGH_PRIORITY_CLASS;
+ else if ( prio <= 100 )
+ dwFlags |= REALTIME_PRIORITY_CLASS;
+ else
+ {
+ wxFAIL_MSG(wxT("invalid value of thread priority parameter"));
+ dwFlags |= NORMAL_PRIORITY_CLASS;
+ }
+ }
+
+ bool ok = ::CreateProcess
+ (
+ // WinCE requires appname to be non null
+ // Win32 allows for null
+#ifdef __WXWINCE__
+ moduleName.t_str(), // application name
+ wxMSW_CONV_LPTSTR(arguments), // arguments
+#else
+ NULL, // application name (use only cmd line)
+ wxMSW_CONV_LPTSTR(command), // full command line
+#endif
+ NULL, // security attributes: defaults for both
+ NULL, // the process and its main thread
+ redirect, // inherit handles if we use pipes
+ dwFlags, // process creation flags
+ envBuffer.data(), // environment (may be NULL which is fine)
+ useCwd // initial working directory
+ ? wxMSW_CONV_LPTSTR(env->cwd)
+ : NULL, // (or use the same)
+ &si, // startup info (unused here)
+ &pi // process info
+ ) != 0;
+
+#if wxUSE_STREAMS && !defined(__WXWINCE__)
+ // we can close the pipe ends used by child anyhow
+ if ( redirect )
+ {
+ ::CloseHandle(pipeIn.Detach(wxPipe::Read));
+ ::CloseHandle(pipeOut.Detach(wxPipe::Write));
+ ::CloseHandle(pipeErr.Detach(wxPipe::Write));
+ }
+#endif // wxUSE_STREAMS