]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/utilsexc.cpp
Don't use wxCHECK_W32API_VERSION() in #if when it can be undefined.
[wxWidgets.git] / src / msw / utilsexc.cpp
index 8e86fb663c42050eb49e5a3e4b9c7758fd178c6a..734ca45d118f7b2fd43e1126e5b4a9f162aa2e26 100644 (file)
 
 #if !defined(__GNUWIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
     #include <direct.h>
-#ifndef __MWERKS__
     #include <dos.h>
 #endif
-#endif
 
 #if defined(__GNUWIN32__)
     #include <sys/unistd.h>
@@ -82,9 +80,7 @@
     #include "wx/dde.h"         // for WX_DDE hack in wxExecute
 #endif // wxUSE_IPC
 
-// implemented in utils.cpp
-extern "C" WXDLLIMPEXP_BASE HWND
-wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
+#include "wx/msw/private/hiddenwin.h"
 
 // ----------------------------------------------------------------------------
 // constants
@@ -610,7 +606,8 @@ wxExecuteDDE(const wxString& ddeServer,
 
 #endif // wxUSE_IPC
 
-long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
+long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
+               const wxExecuteEnv *env)
 {
     wxCHECK_MSG( !cmd.empty(), 0, wxT("empty command in wxExecute") );
 
@@ -756,15 +753,6 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
         si.hStdOutput = pipeOut[wxPipe::Write];
         si.hStdError = pipeErr[wxPipe::Write];
 
-        // when the std IO is redirected, we don't show the (console) process
-        // window by default, but this can be overridden by the caller by
-        // specifying wxEXEC_NOHIDE flag
-        if ( !(flags & wxEXEC_NOHIDE) )
-        {
-            si.dwFlags |= STARTF_USESHOWWINDOW;
-            si.wShowWindow = SW_HIDE;
-        }
-
         // we must duplicate the handle to the write side of stdin pipe to make
         // it non inheritable: indeed, we must close the writing end of pipeIn
         // before launching the child process as otherwise this handle will be
@@ -789,10 +777,25 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
     }
 #endif // wxUSE_STREAMS
 
+    // The default logic for showing the console is to show it only if the IO
+    // is not redirected however wxEXEC_{SHOW,HIDE}_CONSOLE flags can be
+    // explicitly specified to change it.
+    if ( (flags & wxEXEC_HIDE_CONSOLE) ||
+            (redirect && !(flags & wxEXEC_SHOW_CONSOLE)) )
+    {
+        si.dwFlags |= STARTF_USESHOWWINDOW;
+        si.wShowWindow = SW_HIDE;
+    }
+
+
     PROCESS_INFORMATION pi;
     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
@@ -800,6 +803,55 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
     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;
+        }
+    }
+
     bool ok = ::CreateProcess
                 (
                     // WinCE requires appname to be non null
@@ -818,8 +870,10 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
                  NULL,               //   the process and its main thread
                  redirect,           // inherit handles if we use pipes
                  dwFlags,            // process creation flags
-                 NULL,               // environment (use the same)
-                 NULL,               // current directory (use the same)
+                 envBuffer.data(),   // environment (may be NULL which is fine)
+                 useCwd              // initial working directory
+                    ? const_cast<wxChar *>(env->cwd.wx_str())
+                    : NULL,          //     (or use the same)
                  &si,                // startup info (unused here)
                  &pi                 // process info
                 ) != 0;
@@ -958,7 +1012,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
                 wxFAIL_MSG( wxT("unexpected WaitForInputIdle() return code") );
                 // fall through
 
-            case -1:
+            case WAIT_FAILED:
                 wxLogLastError(wxT("WaitForInputIdle() in wxExecute"));
 
             case WAIT_TIMEOUT:
@@ -1039,7 +1093,8 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
 }
 
 template <typename CharType>
-long wxExecuteImpl(CharType **argv, int flags, wxProcess *handler)
+long wxExecuteImpl(CharType **argv, int flags, wxProcess *handler,
+                   const wxExecuteEnv *env)
 {
     wxString command;
     command.reserve(1024);
@@ -1078,19 +1133,21 @@ long wxExecuteImpl(CharType **argv, int flags, wxProcess *handler)
         command += ' ';
     }
 
-    return wxExecute(command, flags, handler);
+    return wxExecute(command, flags, handler, env);
 }
 
-long wxExecute(char **argv, int flags, wxProcess *handler)
+long wxExecute(char **argv, int flags, wxProcess *handler,
+               const wxExecuteEnv *env)
 {
-    return wxExecuteImpl(argv, flags, handler);
+    return wxExecuteImpl(argv, flags, handler, env);
 }
 
 #if wxUSE_UNICODE
 
-long wxExecute(wchar_t **argv, int flags, wxProcess *handler)
+long wxExecute(wchar_t **argv, int flags, wxProcess *handler,
+               const wxExecuteEnv *env)
 {
-    return wxExecuteImpl(argv, flags, handler);
+    return wxExecuteImpl(argv, flags, handler, env);
 }
 
 #endif // wxUSE_UNICODE