Launch an NSTask and bring it to front

Launch an NSTask and bring it to front

I'm trying to launch another application using NSTask

NSArray* argArray = [NSArray arrayWithObjects:fileName, nil];

NSTask* task = [NSTask launchedTaskWithLaunchPath:appName arguments:argArray];

while this works the main gui window doesn't come to front.

when repeatedly calling with different fileName the new file does get loaded in the app even though only 1 instance of the app is running

any poiners? I did try SetFrontProcess but seems to have no effect even after introducing a delay

I did look into NSRunningApplication but it seems it is not available on 10.5 whereas I need a solution for both 10.5 and 10.6

objective-c nstask

share|improve this question

asked Feb 8 '11 at 0:39

d6d6e832034b6ee35ffecb3d66795e72.png

user549164

7810



4 Answers

active

oldest

votes

up vote

3

down vote

Don't use NSTask to launch applications. Use NSWorkspace, which has several methods (e.g. -launchApplication:) to launch and activate an application.

share|improve this answer

answered Feb 8 '11 at 1:21

1ebe99fd25ad376dad53b12322dd1337.jpg

indragie

7,209248104



 

There is a problem with using NSWorkspace I want to pass a file name as the argument in NSWorkspace functions if the app is already running meaning new instance is not created the argument part is ignored which makes it unusable in this scenario –  user549164 Feb 8 '11 at 1:47


 

Well in that case, maybe launch the app using NSTask and then use one of the NSWorkspace launching methods right after, because the NSWorkspace methods will bring the application to the front if it is already running. –  indragie Feb 8 '11 at 3:30


 

@user549164: You can provide NSWorkspaceLaunchNewInstance to always launch a new instance, if that's appropriate. –  Patrick May 18 at 15:11

english-728.png

up vote

1

down vote

I grabbed these from my MDFoundationAdditions and MDAppKitAdditions categories.

This solution should work for Mac OS X 10.4.x and later (which is when LSOpenApplication() was introduced):

MDAppKitAdditions.h:

#import <Cocoa/Cocoa.h>

#import "MDFoundationAdditions.h"


@interface NSWorkspace (MDAdditions)

- (BOOL)launchApplicationAtPath:(NSString *)path

          arguments:(NSArray *)argv

            error:(NSError **)error;

@end

MDAppKitAdditions.m:

#import "MDAppKitAdditions.h"

#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4

#include <ApplicationServices/ApplicationServices.h>

#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5

#include <CoreServices/CoreServices.h>

#endif


@implementation NSWorkspace (MDAdditions)


- (BOOL)launchApplicationAtPath:(NSString *)path arguments:(NSArray *)argv

             error:(NSError **)error {

    BOOL success = YES;

        if (error) *error = nil;


        if (path) {

            FSRef itemRef;

            if ([path getFSRef:&itemRef error:error]) {

                LSApplicationParameters appParameters =

                  {0, kLSLaunchDefaults, &itemRef, NULL, NULL,

                (argv ? (CFArrayRef)argv : NULL), NULL };


                OSStatus status = noErr;

                status = LSOpenApplication(&appParameters, NULL);


                if (status != noErr) {

                    success = NO;

                    NSLog(@"[%@ %@] LSOpenApplication() returned %hi for %@",

                        NSStringFromClass([self class]),

                        NSStringFromSelector(_cmd), status, path);

                    if (error) *error =

        [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil];

            }

        }

    }

    return success;

}

@end

MDFoundationAdditions.h:

#import <Foundation/Foundation.h>

#import <CoreServices/CoreServices.h>


@interface NSString (MDAdditions)

- (BOOL)getFSRef:(FSRef *)anFSRef error:(NSError **)anError;

@end

MDFoundationAdditions.h:

#import "MDFoundationAdditions.h"

#import <sys/syslimits.h>


@implementation NSString (MDAdditions)


- (BOOL)getFSRef:(FSRef *)anFSRef error:(NSError **)anError {

    if (anError) *anError = nil;

    OSStatus status = noErr;

    status = FSPathMakeRef((const UInt8 *)[self UTF8String], anFSRef, NULL);

    if (status != noErr) {

        if (anError)

    *anError = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil];

    }

    return (status == noErr);

}

@end

share|improve this answer

answered Feb 8 '11 at 13:17

NjKo2.png

NSGod

11.8k1232



up vote

0

down vote

If the task you want to launch is a proper application, you can use NSWorkspace's

  • (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag

share|improve this answer

answered Feb 8 '11 at 3:52

71730cfb2f74b37c582cb764e6f800cf.png

jon

111



 

I've tried this but there seems to be a problem in passing arguments which have ' ' spaces int like a long file path with spaces. I tried passing in with quotes but the function returns an error –  user549164 Feb 8 '11 at 20:36


 

the app doesn't open file if there are spaces in filename –  user549164 Feb 8 '11 at 21:19

up vote

0

down vote

To expand on indragie's answer, if you want a new instance launched with a file argument, do something like (untested):

NSDictionary *config = [NSDictionary dictionaryWithObjectsAndKeys:

                         [NSArray arrayWithObject:filePath], NSWorkspaceLaunchConfigurationArguments,

                         nil];

NSError *error = nil;

[[NSWorkspace sharedWorkspace] launchApplicationAtURL:yourAppURL options:NSWorkspaceLaunchNewInstance | NSWorkspaceLaunchDefault configuration:config error:&error]

On 10.5, you might try (not tested):

NSURL *fileURL = [NSURL fileURLWithPath:filePath];

[[NSWorkspace sharedWorkspace] openURLs:[NSArray arrayWithObject:fileURL] withAppBundleIdentifier:@"com.foo.someapp" options:NSWorkspaceLaunchNewInstance | NSWorkspaceLaunchDefault additionalEventParamDescriptor:nil launchIdentifiers:nil];

share|improve this answer

edited Feb 8 '11 at 22:10



answered Feb 8 '11 at 3:53

d45a26aad5d401a93a4efcc31688d06c.png

Wevah

14.8k23643



 

NSWorkspaceLaunchConfigurationArguments is only available in 10.6 or later –  user549164 Feb 8 '11 at 21:06


 

Then you'll probably have to use launchAppWithBundleIdentifier:... and construct your own Apple Event to pass in the file. –  Wevah Feb 8 '11 at 22:06


 

Actually... [edits answer] –  Wevah Feb 8 '11 at 22:08


 

other app doesn't have a bundle identifier :( –  user549164 Feb 10 '11 at 0:01


 

Is it an older app? I don't think I've come across one without a bundle identifier in a while… –  Wevah Feb 10 '11 at 0:09

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值