使用NSAppleScript创建并调用Objective C中的AppleScript应用程序具有不同的结果和相同的代码?
首先,我已经创建了下面的代码一个AppleScript应用程序(文件名:UnloadTest.scpt):使用NSAppleScript创建并调用Objective C中的AppleScript应用程序具有不同的结果和相同的代码?
-- Set user name and password
set UserName to "MyAccount"
set MyPASSWORD to "MyPassword"
-- unload FTDIUSBSerialDriver
do shell script "sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext" user name UserName password MyPASSWORD with administrator privileges
-- Copy driver to the used location
do shell script "sudo cp ./libftd2xx.1.0.2.dylib /usr/local/lib" user name UserName password MyPASSWORD with administrator privileges
do shell script "sudo cp ./libd2xx_table.dylib /usr/local/lib" user name UserName password MyPASSWORD with administrator privileges
do shell script "cd /usr/local/lib" user name UserName password MyPASSWORD with administrator privileges
do shell script "sudo ln -sf libftd2xx.1.0.2.dylib libftd2xx.dylib" user name UserName password MyPASSWORD with administrator privileges
而且使用NSAppleScript类来调用它,如下面的代码:
NSString * strScript = [[NSBundle mainBundle] pathForResource:@"UnloadTest" ofType:@"scpt"];
NSAppleScript * appScript = [[NSAppleScript alloc] initWithContentsOfURL:[NSURL fileURLWithPath:strScript] error:nil];
[appScript executeAndReturnError:NULL];
[appScript release];
它可以正常工作,但它有一个问题:如果我想在另一台计算机上运行我的APP,我需要将UserName和MyPASSWORD更改为其他人的“UnloadTest.scpt”文件,这很愚蠢!所以我想走另一条路:用“ - (ID)initWithSource:(的NSString *)源代码”功能,从代码中创建一个AppleScript,我可以从我的应用程序接口发送用户名&密码:
NSString *strScriptUnload = [NSString stringWithFormat:@"\
set UserName to \"%@\"\
set MyPASSWORD to \"%@\"\
do shell script \"sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext\" user name UserName password MyPASSWORD with administrator privileges\
do shell script \"sudo cp ./libftd2xx.1.0.2.dylib /usr/local/lib\" user name UserName password MyPASSWORD with administrator privileges\
do shell script \"sudo cp ./libd2xx_table.dylib /usr/local/lib\" user name UserName password MyPASSWORD with administrator privileges\
do shell script \"cd /usr/local/lib\" user name UserName password MyPASSWORD with administrator privileges\
do shell script \"sudo ln -sf libftd2xx.1.0.2.dylib libftd2xx.dylib\" user name UserName password MyPASSWORD with administrator privileges",[m_textUserName stringValue], [m_textPassword stringValue]];
NSAppleScript *appUnloadScript = [[NSAppleScript alloc] initWithSource:strScriptUnload];
returnDescriptor = [appUnloadScript executeAndReturnError:nil];
[appUnloadScript release];
但它对我来说工作失败,看起来像
sudo ln -sf libftd2xx.1.0.2.dylib libftd2xx.dylib
不工作成功。我认为这是AppleScript没有获得特权,但我不知道如何纠正它。
有没有人可以帮助我理解这个问题?
我找到了导致此问题的原因,只是在AppleScript代码行后面缺少“\ n”。下面的代码是成功的:
NSString *strScriptUnload = [NSString stringWithFormat:@"\
set UserName to \"%@\"\n\
set MyPASSWORD to \"%@\"\n\
do shell script \"sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext\" user name UserName password MyPASSWORD with administrator privileges\n\
do shell script \"sudo cp ./libftd2xx.1.0.2.dylib /usr/local/lib\" user name UserName password MyPASSWORD with administrator privileges\n\
do shell script \"sudo cp ./libd2xx_table.dylib /usr/local/lib\" user name UserName password MyPASSWORD with administrator privileges\n\
do shell script \"cd /usr/local/lib\" user name UserName password MyPASSWORD with administrator privileges\n\
do shell script \"sudo ln -sf libftd2xx.1.0.2.dylib libftd2xx.dylib\" user name UserName password MyPASSWORD with administrator privileges\n",[m_textUserName stringValue], [m_textPassword stringValue]];
NSAppleScript *appUnloadScript = [[NSAppleScript alloc] initWithSource:strScriptUnload];
returnDescriptor = [appUnloadScript executeAndReturnError:nil];
[appUnloadScript release];
谢谢大家!
使用字符串消除将参数传递给脚本是不好的做法。在将其输入到字符串之前未能对输入进行消毒处理是一种不好的做法,并且完全不安全。 (如果文本包含双引号或反斜杠会发生什么?)[这是正确的方法来做到这一点。](http://*.com/questions/19759149/cocoa-run-applescript-that-already-contains-double-报价/ 19774696#19774696) – foo
*从不*硬编码用户的登录信息;这是一个巨大的安全违规。使用一个'do shell脚本'set -e; cmd1; cmd2; cmd3; ...“带有管理员权限的命令,这将在继续之前自动提示用户验证一次。 – foo
但这对我并不好,因为我的应用程序需要每次调用AppleScript。如果我按照你的说法这样做,它会提示用户每次验证一次,而不是一次验证。 – Raniys
您的应用程序需要多长时间运行一次该脚本?您的原始文章不提供任何背景信息。 – foo