]> git.saurik.com Git - wxWidgets.git/commitdiff
Add support for launching APPL bundles with wxExecute
authorRyan Norton <wxprojects@comcast.net>
Thu, 21 Apr 2005 19:58:22 +0000 (19:58 +0000)
committerRyan Norton <wxprojects@comcast.net>
Thu, 21 Apr 2005 19:58:22 +0000 (19:58 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33801 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
src/mac/corefoundation/utilsexc_cf.cpp
src/unix/utilsunx.cpp

index ccc8f9a745a55bd372066ee8e4e52b0d845831a5..aeaf72176f2c1e42f1951a9465b8c82233b0fa7b 100644 (file)
@@ -2,6 +2,13 @@
 wxWidgets Change Log - For more verbose changes, see the manual
 ---------------------------------------------------------------
 
+2.6.1
+-----
+All:
+
+wxMac:
+- Added support for launching 'APPL' bundles with wxExecute (usually they have a .app extension and are the ones that reside in the Applications folder).
+
 2.6.0
 -----
 
index afd52277301a4bc1e76cfb4dba01bd2b0e1d7c9f..bb6e19d6ed6634495c95295aa8363abe827b6e94 100644 (file)
@@ -1,11 +1,11 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        src/mac/corefoundation/utilsexec_cf.cpp
 // Purpose:     Execution-related utilities for Darwin
-// Author:      David Elliott
+// Author:      David Elliott, Ryan Norton (wxMacExecute)
 // Modified by: Stefan Csomor (added necessary wxT for unicode builds)
 // Created:     2004-11-04
 // RCS-ID:      $Id$
-// Copyright:   (c) David Elliott
+// Copyright:   (c) David Elliott, Ryan Norton
 // Licence:     wxWindows licence
 // Notes:       This code comes from src/mac/carbon/utilsexc.cpp,1.11
 /////////////////////////////////////////////////////////////////////////////
 #include "wx/stdpaths.h"
 #include "wx/apptrait.h"
 
+#ifdef __WXCOCOA__
+#include <CoreFoundation/CoreFoundation.h>
+#include <ApplicationServices/ApplicationServices.h>
+#else
+#include "wx/mac/private.h"
+#include "LaunchServices.h"
+#endif
+
+#include "wx/uri.h"
+#include "wx/mac/corefoundation/cfstring.h"
+
+long wxMacExecute(wxChar **argv,
+               int flags,
+               wxProcess *process)
+{
+    CFIndex cfiCount = 0;
+    //get count
+    for(wxChar** argvcopy = argv; *argvcopy != NULL ; ++argvcopy)
+    {
+        ++cfiCount;
+    }
+
+    if(cfiCount == 0) //no file to launch?
+    {
+        wxLogDebug(wxT("wxMacExecute No file to launch!"));
+        return -1;
+    }
+    
+    CFURLRef cfurlApp = CFURLCreateWithString(
+            kCFAllocatorDefault,
+            wxMacCFStringHolder(*argv++, wxLocale::GetSystemEncoding()),
+            NULL);
+    wxASSERT(cfurlApp);
+
+    CFBundleRef cfbApp = CFBundleCreate(kCFAllocatorDefault, cfurlApp);
+    if(!cfbApp)
+    {
+        wxLogDebug(wxT("wxMacExecute Bad bundle"));
+        CFRelease(cfurlApp);
+        return -1;
+    }
+    
+    
+    UInt32 dwBundleType, dwBundleCreator;
+    CFBundleGetPackageInfo(cfbApp, &dwBundleType, &dwBundleCreator);
+
+    //Only call wxMacExecute for .app bundles - others could be actual unix programs
+    if(dwBundleType != 'APPL')
+    {
+        CFRelease(cfurlApp);
+        return -1;
+    }
+    
+    //
+    // We have a good bundle - so let's launch it!
+    //
+    
+    CFMutableArrayRef cfaFiles = CFArrayCreateMutable(kCFAllocatorDefault, cfiCount - 1, NULL);
+            
+    wxASSERT(cfaFiles);
+    
+    if(--cfiCount)
+    {
+        for( ; *argv != NULL ; ++argv)
+        {
+//            wxLogDebug(*argv);
+            wxString sCurrentFile;
+            
+            if(wxURI(*argv).IsReference())
+                sCurrentFile = wxString(wxT("file://")) + *argv;
+            else
+                sCurrentFile = *argv;
+                
+            CFURLRef cfurlCurrentFile =   CFURLCreateWithString(
+                    kCFAllocatorDefault,
+                    wxMacCFStringHolder(sCurrentFile, wxLocale::GetSystemEncoding()),
+                    NULL);
+            wxASSERT(cfurlCurrentFile);
+
+            CFArrayAppendValue(
+                cfaFiles,
+                cfurlCurrentFile
+                            );
+        }
+    }
+    
+    LSLaunchURLSpec launchspec;
+    launchspec.appURL = cfurlApp;
+    launchspec.itemURLs = cfaFiles;
+    launchspec.passThruParams = NULL; //AEDesc* 
+    launchspec.launchFlags = kLSLaunchDefaults | kLSLaunchDontSwitch;  //TODO:  Possibly be smarter with flags
+    launchspec.asyncRefCon = NULL;
+    
+    OSStatus status = LSOpenFromURLSpec(&launchspec,
+                        NULL); //2nd is CFURLRef* really launched
+
+    //cleanup
+    CFRelease(cfurlApp);
+    CFRelease(cfaFiles);
+    
+    //check for error
+    if(status != noErr)
+    {
+        wxLogDebug(wxString::Format(wxT("wxMacExecute ERROR: %d")), (int)status);
+        return -1;
+    }
+    return 0; //success
+}
+
+
 #include <CoreFoundation/CFMachPort.h>
 #include <sys/wait.h>
 extern "C" {
index 8336c2d68b11f7e815c6bb404d6e301c7bc2bc33..072a66b54a7f46a0d12f4e6de428ff1e5191e9cd 100644 (file)
@@ -237,6 +237,12 @@ int wxKill(long pid, wxSignal sig, wxKillError *rc, int flags)
 
 #define WXEXECUTE_NARGS   127
 
+#if defined(__DARWIN__)
+long wxMacExecute(wxChar **argv,
+               int flags,
+               wxProcess *process);
+#endif
+
 long wxExecute( const wxString& command, int flags, wxProcess *process )
 {
     wxCHECK_MSG( !command.empty(), 0, wxT("can't exec empty command") );
@@ -307,8 +313,14 @@ long wxExecute( const wxString& command, int flags, wxProcess *process )
     } while(*cptr);
     argv[argc] = NULL;
 
+    long lRc;
+#if defined(__DARWIN__)
+    if( (lRc = wxMacExecute(argv, flags, process)) != -1)
+        return lRc;
+#endif
+
     // do execute the command
-    long lRc = wxExecute(argv, flags, process);
+    lRc = wxExecute(argv, flags, process);
 
     // clean up
     argc = 0;
@@ -436,7 +448,7 @@ bool wxPipeInputStream::CanRead() const
 #ifdef __VMS
     #pragma message disable codeunreachable
 #endif
-
+               
 long wxExecute(wxChar **argv,
                int flags,
                wxProcess *process)
@@ -588,7 +600,7 @@ long wxExecute(wxChar **argv,
         }
 
         execvp (*mb_argv, mb_argv);
-
+       
         fprintf(stderr, "execvp(");
         // CS changed ppc to ppc_ as ppc is not available under mac os CW Mach-O
         for ( char **ppc_ = mb_argv; *ppc_; ppc_++ )