我想知道如何从传递参数的cocoa应用程序中执行applescript。 我已经看到在stackoverflow中执行其他问题中没有参数的applescripts是多么容易,但是使用NSAppleScript类,其中,我没有看到没有解决我的问题的方法。有没有人有任何想法。
我想要一个与此shell具有相同效果的Cocoa代码:
osascript teste.applescript "snow:Users:MyUser:Desktop:MyFolder" "snow:Users:MyUser:Desktop:Example:"
所以它可以运行这个AppleScript。
on run argv
set source to (item 1 of argv)
set destiny to (item 2 of argv)
tell application "Finder" to make new alias file at destiny to source
0
end run
感谢任何帮助。提前谢谢。
答案 0 :(得分:4)
查看我的GitHub存储库,我有一个NSAppleEventDescriptor类别,它可以更容易地创建NSAppleEventDescriptor来调用带有参数的不同AppleScript过程,以及对许多AppleScript类型进行强制操作。
答案 1 :(得分:3)
我发现更容易遵循这段代码。我从here获取了一段代码并将其修改为我的目的。
- (BOOL) executeScriptWithPath:(NSString*)path function:(NSString*)functionName andArguments:(NSArray*)scriptArgumentArray
{
BOOL executionSucceed = NO;
NSAppleScript * appleScript;
NSAppleEventDescriptor * thisApplication, *containerEvent;
NSURL * pathURL = [NSURL fileURLWithPath:path];
NSDictionary * appleScriptCreationError = nil;
appleScript = [[NSAppleScript alloc] initWithContentsOfURL:pathURL error:&appleScriptCreationError];
if (appleScriptCreationError)
{
NSLog([NSString stringWithFormat:@"Could not instantiate applescript %@",appleScriptCreationError]);
}
else
{
if (functionName && [functionName length])
{
/* If we have a functionName (and potentially arguments), we build
* an NSAppleEvent to execute the script. */
//Get a descriptor for ourself
int pid = [[NSProcessInfo processInfo] processIdentifier];
thisApplication = [NSAppleEventDescriptor descriptorWithDescriptorType:typeKernelProcessID
bytes:&pid
length:sizeof(pid)];
//Create the container event
//We need these constants from the Carbon OpenScripting framework, but we don't actually need Carbon.framework...
#define kASAppleScriptSuite 'ascr'
#define kASSubroutineEvent 'psbr'
#define keyASSubroutineName 'snam'
containerEvent = [NSAppleEventDescriptor appleEventWithEventClass:kASAppleScriptSuite
eventID:kASSubroutineEvent
targetDescriptor:thisApplication
returnID:kAutoGenerateReturnID
transactionID:kAnyTransactionID];
//Set the target function
[containerEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithString:functionName]
forKeyword:keyASSubroutineName];
//Pass arguments - arguments is expecting an NSArray with only NSString objects
if ([scriptArgumentArray count])
{
NSAppleEventDescriptor *arguments = [[NSAppleEventDescriptor alloc] initListDescriptor];
NSString *object;
for (object in scriptArgumentArray) {
[arguments insertDescriptor:[NSAppleEventDescriptor descriptorWithString:object]
atIndex:([arguments numberOfItems] + 1)]; //This +1 seems wrong... but it's not
}
[containerEvent setParamDescriptor:arguments forKeyword:keyDirectObject];
[arguments release];
}
//Execute the event
NSDictionary * executionError = nil;
NSAppleEventDescriptor * result = [appleScript executeAppleEvent:containerEvent error:&executionError];
if (executionError != nil)
{
NSLog([NSString stringWithFormat:@"error while executing script. Error %@",executionError]);
}
else
{
NSLog(@"Script execution has succeed. Result(%@)",result);
executionSucceed = YES;
}
}
else
{
NSDictionary * executionError = nil;
NSAppleEventDescriptor * result = [appleScript executeAndReturnError:&executionError];
if (executionError != nil)
{
NSLog([NSString stringWithFormat:@"error while executing script. Error %@",executionError]);
}
else
{
NSLog(@"Script execution has succeed. Result(%@)",result);
executionSucceed = YES;
}
}
}
[appleScript release];
return executionSucceed;
}
答案 2 :(得分:1)
我对AppleScript并不是很熟悉,但我似乎记得它们基于(相当蹩脚的) Apple Events 机制,其历史可以追溯到56k调制解调器的时代。你房子里最酷的小工具。
因此,我猜您正在寻找属于NSAppleScript
的{{3}}。也许你可以找到一些关于如何在NSAppleEventDescriptor
的实例中封装执行参数的信息,你必须传递这个函数。
答案 3 :(得分:0)
技术说明TN2084
在可可应用程序中使用AppleScript脚本
即使使用Cocoa用Objective-C编写应用程序,也可以使用AppleScript脚本执行某些操作。本技术说明介绍了如何在Cocoa应用程序中集成和执行AppleScript。它讨论了如何利用NSAppleScript类以及如何使用NSAppleEventDescriptor将数据发送到接收器。
https://developer.apple.com/library/archive/technotes/tn2084/_index.html
Swift 4版本,从此处的代码进行了修改:
https://gist.github.com/chbeer/3666e4b7b2e71eb47b15eaae63d4192f
import Carbon
static func runAppleScript(_ url: URL) {
var appleScriptError: NSDictionary? = nil
guard let script = NSAppleScript(contentsOf: url, error: &appleScriptError) else {
return
}
let message = NSAppleEventDescriptor(string: "String parameter")
let parameters = NSAppleEventDescriptor(listDescriptor: ())
parameters.insert(message, at: 1)
var psn = ProcessSerialNumber(highLongOfPSN: UInt32(0), lowLongOfPSN: UInt32(kCurrentProcess))
let target = NSAppleEventDescriptor(descriptorType: typeProcessSerialNumber, bytes: &psn, length: MemoryLayout<ProcessSerialNumber>.size)
let handler = NSAppleEventDescriptor(string: "MyMethodName")
let event = NSAppleEventDescriptor.appleEvent(withEventClass: AEEventClass(kASAppleScriptSuite), eventID: AEEventID(kASSubroutineEvent), targetDescriptor: target, returnID: AEReturnID(kAutoGenerateReturnID), transactionID: AETransactionID(kAnyTransactionID))
event.setParam(handler, forKeyword: AEKeyword(keyASSubroutineName))
event.setParam(parameters, forKeyword: AEKeyword(keyDirectObject))
var executeError: NSDictionary? = nil
script.executeAppleEvent(event, error: &executeError)
if let executeError = executeError {
print("ERROR: \(executeError)")
}
}
用于运行Apple脚本:
on MyMethodName(theParameter)
display dialog theParameter
end MyMethodName