How to open a document using an application launched via NSTask?
I've grown tired of the built-in open
Mac OS X command, mostly because it runs programs with your actual user ID instead of the effective user ID; this results in the fact sudo open Foo
opens Foo with its associated application with your account instead of the root
account, and it annoys me. So I decided to make some kind of replacement.
So far I've been successful: I can open any program under the open -a
or open -b
fashion, and support optionally waiting. I'm using NSTask
for that purpose.
However, I'd like to be开发者_如何学运维 able to open documents too. As far as I can see, you need to use NSWorkspace
for that, but using NSWorkspace
to launch programs results in them being launched with your account's credentials instead of your command line program's credentials. Which is precisely what the default open
tool does, and precisely what I don't want.
So, how can I have a program request that another program opens a document without using NSWorkspace
? From the NSTask
object, I can have the process ID, but that's about it.
Hopefully this will do the trick:
- (void)openFile:(NSString *)filePath withTask:(NSTask *)task {
int pid = [task processIdentifier];
NSAppleEventDescriptor *target = [NSAppleEventDescriptor descriptorWithDescriptorType:typeKernelProcessID bytes:&pid length:sizeof(pid)];
const char *urlUTF8 = [[[NSURL fileURLWithPath:filePath] absoluteString] UTF8String];
NSAppleEventDescriptor *urlDescriptor = [NSAppleEventDescriptor descriptorWithDescriptorType:typeFileURL bytes:urlUTF8 length:strlen(urlUTF8)];
NSAppleEventDescriptor *event = [NSAppleEventDescriptor appleEventWithEventClass:kEventParamAppleEvent eventID:kAEOpen targetDescriptor:target returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
[event setParamDescriptor:urlDescriptor forKeyword:keyDirectObject];
OSStatus err = AESendMessage([event aeDesc], NULL, kAENoReply | kAENeverInteract, kAEDefaultTimeout);
if (err != noErr) {
// Error handling goes here
}
// Activate the application
event = [NSAppleEventDescriptor appleEventWithEventClass:kAEMiscStandards eventID:kAEActivate targetDescriptor:target returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
err = AESendMessage([event aeDesc], NULL, kAENoReply | kAENeverInteract, kAEDefaultTimeout);
}
You may have to launch the application using an
NSTask
and then send it the appropriate open Apple Event.Actually, can you launch using an
NSTask
and then open the file viaNSWorkspace
once you know it's running? Or does that launch a new instance of the application under your user?Original reply:
Does
open -a SomeApplication SomeFile
work?
精彩评论