Add support for launching APPL bundles with wxExecute
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33801 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -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
|
||||
-----
|
||||
|
||||
|
@@ -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
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -19,6 +19,116 @@
|
||||
#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" {
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user