예제 #1
0
파일: main.c 프로젝트: Deanzou/ppp
/* -----------------------------------------------------------------------------
 use launch services to launch an application
 return < 0 if the application cannot be launched
----------------------------------------------------------------------------- */
static int launch_app(char *app, char *params)
{
#ifdef HAVE_LAUNCHSERVICES

    CFURLRef 		urlref;
    LSLaunchURLSpec 	urlspec;
    OSStatus 		err;
#if 0
    OSErr		oserr;
    AEDesc		desc;
#endif

    urlref = CFURLCreateFromFileSystemRepresentation(NULL, (u_char*)app, strlen(app), FALSE);
    if (urlref == 0) 
        return -1;
    
#if 0
    oserr = AECreateDesc(typeChar, params, strlen(params), &desc);
    if (oserr != noErr) {
        CFRelease(urlref);
        return -1;
    }
#endif

    urlspec.appURL = urlref;
    urlspec.itemURLs = 0;
    urlspec.passThruParams = 0;
#if 0
    urlspec.passThruParams = &desc;
#endif 
    urlspec.launchFlags = kLSLaunchAsync + kLSLaunchDontAddToRecents 
                + kLSLaunchNewInstance + kLSLaunchNoParams;
    urlspec.asyncRefCon = 0;
        
    err = LSOpenFromURLSpec(&urlspec, NULL);
    if (err != 0) {
#if 0
        AEDisposeDesc(&desc);
#endif 
        CFRelease(urlref);
        return -2;
    }

#if 0
    AEDisposeDesc(&desc);
#endif 
    CFRelease(urlref);
	
#endif /* HAVE_LAUNCHSERVICES */
    return 0;
}
예제 #2
0
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//    wxMacLaunch
//
// argv is the command line split up, with the application path first
// flags are the flags from wxExecute
// process is the process passed from wxExecute for pipe streams etc.
// returns -1 on error for wxEXEC_SYNC and 0 on error for wxEXEC_ASYNC
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bool wxMacLaunch(char **argv)
{
    // Obtains the number of arguments for determining the size of
    // the CFArray used to hold them
    CFIndex cfiCount = 0;
    for(char** argvcopy = argv; *argvcopy != NULL ; ++argvcopy)
    {
        ++cfiCount;
    }

    // If there is not a single argument then there is no application
    // to launch
    if(cfiCount == 0)
    {
        wxLogDebug(wxT("wxMacLaunch No file to launch!"));
        return false ;
    }

    // Path to bundle
    wxString path = *argv++;

    // Create a CFURL for the application path
    // Created this way because we are opening a bundle which is a directory
    CFURLRef cfurlApp =
        CFURLCreateWithFileSystemPath(
            kCFAllocatorDefault,
            wxCFStringRef(path),
            kDefaultPathStyle,
            true); //false == not a directory

    // Check for error from the CFURL
    if(!cfurlApp)
    {
        wxLogDebug(wxT("wxMacLaunch Can't open path: %s"), path.c_str());
        return false ;
    }

    // Create a CFBundle from the CFURL created earlier
    CFBundleRef cfbApp = CFBundleCreate(kCFAllocatorDefault, cfurlApp);

    // Check to see if CFBundleCreate returned an error,
    // and if it did this was an invalid bundle or not a bundle
    // at all (maybe a simple directory etc.)
    if(!cfbApp)
    {
        wxLogDebug(wxT("wxMacLaunch Bad bundle: %s"), path.c_str());
        CFRelease(cfurlApp);
        return false ;
    }

    // Get the bundle type and make sure its an 'APPL' bundle
    // Otherwise we're dealing with something else here...
    UInt32 dwBundleType, dwBundleCreator;
    CFBundleGetPackageInfo(cfbApp, &dwBundleType, &dwBundleCreator);
    if(dwBundleType != 'APPL')
    {
        wxLogDebug(wxT("wxMacLaunch Not an APPL bundle: %s"), path.c_str());
        CFRelease(cfbApp);
        CFRelease(cfurlApp);
        return false ;
    }

    // Create a CFArray for dealing with the command line
    // arguments to the bundle
    CFMutableArrayRef cfaFiles = CFArrayCreateMutable(kCFAllocatorDefault,
                                    cfiCount-1, &kCFTypeArrayCallBacks);
    if(!cfaFiles) //This should never happen
    {
        wxLogDebug(wxT("wxMacLaunch Could not create CFMutableArray"));
        CFRelease(cfbApp);
        CFRelease(cfurlApp);
        return false ;
    }

    // Loop through command line arguments to the bundle,
    // turn them into CFURLs and then put them in cfaFiles
    // For use to launch services call
    for( ; *argv != NULL ; ++argv)
    {
        // Check for '<' as this will ring true for
        // CFURLCreateWithString but is generally not considered
        // typical on mac but is usually passed here from wxExecute
        if (wxStrcmp(*argv, wxT("<")) == 0)
            continue;


        CFURLRef cfurlCurrentFile;    // CFURL to hold file path
        wxFileName argfn(*argv);     // Filename for path

        if(argfn.DirExists())
        {
            // First, try creating as a directory
            cfurlCurrentFile = CFURLCreateWithFileSystemPath(
                                kCFAllocatorDefault,
                                wxCFStringRef(*argv),
                                kDefaultPathStyle,
                                true); //true == directory
        }
        else if(argfn.FileExists())
        {
            // And if it isn't a directory try creating it
            // as a regular file
            cfurlCurrentFile = CFURLCreateWithFileSystemPath(
                                kCFAllocatorDefault,
                                wxCFStringRef(*argv),
                                kDefaultPathStyle,
                                false); //false == regular file
        }
        else
        {
            // Argument did not refer to
            // an entry in the local filesystem,
            // so try creating it through CFURLCreateWithString
            cfurlCurrentFile = CFURLCreateWithString(
                                kCFAllocatorDefault,
                                wxCFStringRef(*argv),
                                NULL);
        }

        // Continue in the loop if the CFURL could not be created
        if(!cfurlCurrentFile)
        {
            wxLogDebug(
                wxT("wxMacLaunch Could not create CFURL for argument:%s"),
                *argv);
            continue;
        }

        // Add the valid CFURL to the argument array and then
        // release it as the CFArray adds a ref count to it
        CFArrayAppendValue(
            cfaFiles,
            cfurlCurrentFile
                        );
        CFRelease(cfurlCurrentFile); // array has retained it
    }

    // Create a LSLaunchURLSpec for use with LSOpenFromURLSpec
    // Note that there are several flag options (launchFlags) such
    // as kLSLaunchDontSwitch etc. and maybe we could be more
    // picky about the flags we choose
    LSLaunchURLSpec launchspec;
    launchspec.appURL = cfurlApp;
    launchspec.itemURLs = cfaFiles;
    launchspec.passThruParams = NULL; //AEDesc*
    launchspec.launchFlags = kLSLaunchDefaults;
    launchspec.asyncRefCon = NULL;

    // Finally, call LSOpenFromURL spec with our arguments
    // 2nd parameter is a pointer to a CFURL that gets
    // the actual path launched by the function
    OSStatus status = LSOpenFromURLSpec(&launchspec, NULL);

    // Cleanup corefoundation references
    CFRelease(cfbApp);
    CFRelease(cfurlApp);
    CFRelease(cfaFiles);

    // Check for error from LSOpenFromURLSpec
    if(status != noErr)
    {
        wxLogDebug(wxT("wxMacLaunch LSOpenFromURLSpec Error: %d"),
                   (int)status);
        return false ;
    }

    // No error from LSOpenFromURLSpec, so app was launched
    return true ;
}