Launch an NSTask and bring it to front
来源:互联网 发布:NSIS软件 编辑:程序博客网 时间:2024/05/17 04:42
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-cnstask
share|improve this question
asked Feb 8 '11 at 0:39
user549164
7810
4 Answers
active
oldest
votes
up vote
3
down vote
Don't use NSTask to launch applications. UseNSWorkspace, which has several methods (e.g.-launchApplication:) to launch and activate an application.
share|improve this answer
answered Feb 8 '11 at 1:21
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 – user549164Feb 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. – indragieFeb 8 '11 at 3:30
@user549164: You can provide NSWorkspaceLaunchNewInstance to always launch a new instance, if that's appropriate. – PatrickMay 18 at 15:11
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([selfclass]),
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((constUInt8 *)[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
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
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 – user549164Feb 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
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. – WevahFeb 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… – WevahFeb 10 '11 at 0:09
- Launch an NSTask and bring it to front
- [Front-end] Bring Premium Pixels to Life
- Axure RP Pro - jQuery - "Bring to Front" Interaction
- PB用语句实现控件的Bring to Front和Send to Back
- How to bring a subView to the front a UIView OR toBack a UIView
- An instance of “(null)” is already running. Choose “Stop” to terminate and launch a new instance.
- Merge Sort and apply it to an interview question
- 关于delphi7中Edit菜单栏中bring to Front 和 send to back 连个功能的使用。
- How to Install NoCat Splash and Link it to an External Web Server
- How to snap an OpenGL client and send it to the clipboard
- Magento. How to create an attribute and apply it to products
- How to launch an Executable from within memory
- louis vuitton soldes Hermes is a famous mark bring to an end the world
- Create a New SharePoint Permission Level and Bind it to an Existing SharePoint Group
- NSTask
- C/C++ launch a subprocess and wait it finish
- Its Easy to Launch a Wireless Deauthentication Attack
- How Improved Short-Circuit Local Reads Bring Better Performance and Security to Hadoop
- TI 16位 3.3V--5V 电平转换芯片 SN74ALVC164245
- RMAN 系列(五),RMAN 还原 与 恢复
- iphone开发中的一些小技巧
- Cocos2d-x的SneakyInput
- VPS的CentOS中时间同步方法
- Launch an NSTask and bring it to front
- 系统启动过程简介
- html设置元素水平或垂直居中
- Media Foundation系列文章索引
- iOS提交iTunes审核时出现Invalid Binary错误
- java 文件加密解密
- windows linux 文件传输
- ubunbu下环境变量配置
- 简单的CSS使用举例