4

我想知道是否可以在 Mac 应用程序之间传递参数,如果可能,如何传递。

我知道在 Java 中可以使用命令行中的以下语法:

java JavaApp arg1 arg2 arg3 arg4

这可以通过 main 的 args[] 数组访问它们。

public static void main(String[] args) {
        System.out.println("d");
        for (int i = 0; i < args.length; i++)
            System.out.println(args[i]);
}

编辑:我想将命令行Mac 应用程序中的参数传递给Cocoa Mac应用程序

4

4 回答 4

3

我不清楚为什么您的 Restarter 应用程序需要是 Cocoa 应用程序。但是,假设确实如此,命令行参数在 NSUserDefaults 的参数域中可用。 此链接显示如何从命令行调用程序以及如何指定默认名称。

启动单独进程的 Cocoa 方法是使用NSTask

于 2012-05-15T15:29:42.677 回答
1

如果命令行和 GUI 应用程序都是用 Objective-C 编写的,您可能会使用NSDistributedNotificationCenter它在进程之间发送通知。NSDistributedNotificationCenter 的文档可以在Notification Programming Guide中找到。

C或者,Cocoa GUI 应用程序以与任何其他程序相同的方式接受命令行参数,即子程序的argvargc参数。main

于 2012-05-15T15:22:49.837 回答
1

以下是我写的一个类别,NSWorkspace它允许将argv参数类型数组传递给生成的应用程序。

@interface NSWorkspace (MDAdditions)
- (BOOL)launchApplicationAtPath:(NSString *)path
                      arguments:(NSArray *)argv
                          error:(NSError **)outError;
@end

@implementation NSWorkspace (MDAdditions)

- (BOOL)launchApplicationAtPath:(NSString *)path
                      arguments:(NSArray *)argv
                          error:(NSError **)outError {
    NSParameterAssert(path != nil);
    BOOL success = YES;
    if (outError) *outError = nil;
    FSRef itemRef;
    OSStatus status = FSPathMakeRef((const UInt8 *)[path UTF8String], &itemRef, NULL);
    if (status != noErr) {
        if (anError) *anError = [NSError errorWithDomain:NSOSStatusErrorDomain
                        code:status userInfo:nil];
        return NO;
    }
    LSApplicationParameters appParameters = {0, kLSLaunchDefaults, &itemRef,
         NULL, NULL, (argv ? (CFArrayRef)argv : NULL), NULL };
    status = LSOpenApplication(&appParameters, NULL);
    if (status != noErr) {
         NSLog(@"LSOpenApplication() returned %d for %@", (int)status, path);
         if (outError) *outError = [NSError errorWithDomain:NSOSStatusErrorDomain
                        code:status userInfo:nil];
         return NO;
    }
    return YES;
}
@end

更新:

正如在 Objective-C 中访问命令行参数的答案中所提到的, and函数的“ _”前缀通常表明它们是私有的,如果有可用的替代方案(有),则应避免使用。_NSGetArgv()_NSGetArgc()

要将 args 传递给可执行文件,可以使用NSProcessInfo'-arguments方法,如下代码所示:

NSArray *argv = [[NSProcessInfo processInfo] arguments];
NSArray *args = [argv subarrayWithRange:NSMakeRange(1, argv.count - 1)];
NSLog(@"args == %@", args);
于 2012-05-15T15:52:47.450 回答
0

您的所有答案对我来说都很有效,但我找到了另一种更适合我需求的解决方案。我需要从命令行工具启动 Cocoa 应用程序,我通过以下行实现了这一点:

system("nohup /PATH/Arguments.app/Contents/MacOS/Arguments argument1 argument2 &");

nohup是 unix 服务,它允许您将进程附加到自身,因此如果您关闭终端窗口,该进程将保持活动状态。

出现的下一个问题是从 Cocoa 应用程序中捕获参数。AppDelegate.m“如果main.m是接收它们并只返回一个 int 的那个,我将如何获取参数。”

在 Apple 的框架和库中,我找到了一个完全解决了这个问题的。这个库名为crt_externs.h,包含两个有用的变量,一个用于学习参数的数量,另一个用于获取参数本身。

extern char ***_NSGetArgv(void);
extern int *_NSGetArgc(void);

因此,在 Cocoa 应用程序的AppDelegate内部,我们将编写以下代码来将参数解析为NSString

char **argv = *_NSGetArgv();
NSString *argument1 = [NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding];
NSString *argument2 = [NSString stringWithCString:argv[2] encoding:NSUTF8StringEncoding];

正如我们所见,我们直接跳到参数数组的位置 1,因为位置 0 包含路径本身:

argv[0] = '/PATH/Arguments.app/Contents/MacOS/Arguments'
argv[1] = 'argument1'
argv[2] = 'argument2'

感谢大家的时间和帮助。我从你们那里学到了很多。我也希望这个答案对其他人有帮助:)

干杯和快乐的编码!

于 2012-05-18T08:56:45.090 回答