启动 NSTask 并将其置于最前面

发布于 2024-10-16 21:19:34 字数 425 浏览 2 评论 0原文

我正在尝试使用 NSTask 启动另一个应用程序

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

,但主 gui 窗口不会出现在前面。

当使用不同的文件名重复调用时,即使应用程序只有 1 个实例正在运行

任何指针,新文件也会加载到应用程序中吗?我确实尝试了 SetFrontProcess 但即使在引入延迟后似乎也没有效果

我确实查看了 NSRunningApplication 但它似乎在 10.5 上不可用,而我需要针对 10.5 和 10.6 的解决方案

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

沧笙踏歌 2024-10-23 21:19:34

不要使用 NSTask 启动应用程序。使用 NSWorkspace ,它有多种方法(例如-launchApplication:)来启动和激活应用程序。

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

最后的乘客 2024-10-23 21:19:34

我从我的 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

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
迷爱 2024-10-23 21:19:34

为了扩展 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];

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];
夕色琉璃 2024-10-23 21:19:34

如果你要启动的任务是一个合适的应用程序,你可以使用 NSWorkspace 的

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文