1

NSTask を使用して別のアプリケーションを起動しようとしています

NSArray* argArray = [NSArray arrayWithObjects:fileName, nil];
NSTask* task = [NSTask launchedTaskWithLaunchPath:appName arguments:argArray];

これが機能している間、メインの GUI ウィンドウは前面に表示されません。

別のファイル名で繰り返し呼び出すと、アプリのインスタンスが 1 つしか実行されていない場合でも、新しいファイルがアプリに読み込まれます

ポインターはありますか?試してみSetFrontProcessましたが、遅延を導入しても効果がないようです

NSRunningApplication を調べましたが、10.5 では利用できないようですが、10.5 と 10.6 の両方のソリューションが必要です

4

4 に答える 4

3

NSTaskアプリケーションの起動には使用しないでください。NSWorkspaceを使用します。これには-launchApplication:、アプリケーションを起動してアクティブ化するためのいくつかの方法 (例: ) があります。

于 2011-02-08T01:21:49.397 に答える
1

私は自分のMDFoundationAdditionsMDAppKitAdditionsカテゴリからこれらをつかみました。

このソリューションは、Mac OS X 10.4.x 以降 (LSOpenApplication() が導入されたとき) で機能するはずです。

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
于 2011-02-08T13:17:15.810 に答える
0

起動したいタスクが適切なアプリケーションである場合は、NSWorkspace の

- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName
    andDeactivate:(BOOL)flag
于 2011-02-08T03:52:29.047 に答える
0

indragie の回答を拡張するには、ファイル引数を使用して新しいインスタンスを起動する場合は、次のようにします (未テスト):

NSDictionary *config = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSArray arrayWithObject:filePath], NSWorkspaceLaunchConfigurationArguments,
                         nil];
NSError *error = nil;
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:yourAppURL options:NSWorkspaceLaunchNewInstance | NSWorkspaceLaunchDefault configuration:config error:&error]

10.5 では、次のことを試すことができます (テストされていません)。

NSURL *fileURL = [NSURL fileURLWithPath:filePath];
[[NSWorkspace sharedWorkspace] openURLs:[NSArray arrayWithObject:fileURL] withAppBundleIdentifier:@"com.foo.someapp" options:NSWorkspaceLaunchNewInstance | NSWorkspaceLaunchDefault additionalEventParamDescriptor:nil launchIdentifiers:nil];
于 2011-02-08T03:53:44.933 に答える