如何使用 Perl 中的 OS-X ScriptingBridge 框架关闭窗口?
问题...
自从MacPerl 不再支持 64 位 perl,我正在尝试替代框架来控制 Terminal.app。
我正在尝试 ScriptingBridge,但遇到了使用 PerlObjCBridge。
我想打电话:
typedef enum {
TerminalSaveOptionsYes = 'yes ' /* Save the file. */,
TerminalSaveOptionsNo = 'no ' /* Do not save the file. */,
TerminalSaveOptionsAsk = 'ask ' /* Ask the user whether or not to save the file. */
} TerminalSaveOptions;
- (void) closeSaving:(TerminalSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
尝试的解决方案...
我已经尝试过:
#!/usr/bin/perl
use strict;
use warnings;
use Foundation;
# Load the ScriptingBridge framework
NSBundle->bundleWithPath_('/System/Library/Frameworks/ScriptingBridge.framework')->load;
@SBApplication::ISA = qw(PerlObjCBridge);
# Set up scripting bridge for Terminal.app
my $terminal = SBApplication->applicationWithBundleIdentifier_("com.apple.terminal");
# Open a new window, get back the tab
my $tab = $terminal->doScript_in_('exec sleep 60', undef);
warn "Opened tty: ".$tab->tty->UTF8String; # Yes, it is a tab
# Now try to close it
# Simple idea
eval { $tab->closeSaving_savingIn_('no ', undef) }; warn $@ if $@;
# Try passing a string ref
my $no = 'no ';
eval { $tab->closeSaving_savingIn_(\$no, undef) }; warn $@ if $@;
# Ok - get a pointer to the string
my $pointer = pack("P4", $no);
eval { $tab->closeSaving_savingIn_($pointer, undef) }; warn $@ if $@;
eval { $tab->closeSaving_savingIn_(\$pointer, undef) }; warn $@ if $@;
# Try a pointer decodes as an int, like PerlObjCBridge uses
my $int_pointer = unpack("L!", $pointer);
eval { $tab->closeSaving_savingIn_($int_pointer, undef) }; warn $@ if $@;
eval { $tab->closeSaving_savingIn_(\$int_pointer, undef) }; warn $@ if $@;
# Aaarrgghhhh....
如您所见,我对如何传递枚举字符串的所有猜测都失败了。
在你攻击我之前...
- 我知道我可以使用另一种语言(ruby、python、cocoa)来做到这一点,但这需要翻译其余的代码。
- 我也许可以使用 CamelBones,但我不想假设我的用户拥有它安装。
- 我还可以使用 NSAppleScript 框架(假设我费尽心思找到选项卡和窗口 ID),但仅仅为了这一次调用就必须求助于它似乎很奇怪。
Problem...
Since MacPerl is no longer supported on 64bit perl, I am trying alternative frameworks to control Terminal.app.
I am trying the ScriptingBridge, but have run into a problem passing an enumerated string to the closeSaving
method using the PerlObjCBridge.
I want to call:
typedef enum {
TerminalSaveOptionsYes = 'yes ' /* Save the file. */,
TerminalSaveOptionsNo = 'no ' /* Do not save the file. */,
TerminalSaveOptionsAsk = 'ask ' /* Ask the user whether or not to save the file. */
} TerminalSaveOptions;
- (void) closeSaving:(TerminalSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
Attempted Solution...
I have tried:
#!/usr/bin/perl
use strict;
use warnings;
use Foundation;
# Load the ScriptingBridge framework
NSBundle->bundleWithPath_('/System/Library/Frameworks/ScriptingBridge.framework')->load;
@SBApplication::ISA = qw(PerlObjCBridge);
# Set up scripting bridge for Terminal.app
my $terminal = SBApplication->applicationWithBundleIdentifier_("com.apple.terminal");
# Open a new window, get back the tab
my $tab = $terminal->doScript_in_('exec sleep 60', undef);
warn "Opened tty: ".$tab->tty->UTF8String; # Yes, it is a tab
# Now try to close it
# Simple idea
eval { $tab->closeSaving_savingIn_('no ', undef) }; warn $@ if $@;
# Try passing a string ref
my $no = 'no ';
eval { $tab->closeSaving_savingIn_(\$no, undef) }; warn $@ if $@;
# Ok - get a pointer to the string
my $pointer = pack("P4", $no);
eval { $tab->closeSaving_savingIn_($pointer, undef) }; warn $@ if $@;
eval { $tab->closeSaving_savingIn_(\$pointer, undef) }; warn $@ if $@;
# Try a pointer decodes as an int, like PerlObjCBridge uses
my $int_pointer = unpack("L!", $pointer);
eval { $tab->closeSaving_savingIn_($int_pointer, undef) }; warn $@ if $@;
eval { $tab->closeSaving_savingIn_(\$int_pointer, undef) }; warn $@ if $@;
# Aaarrgghhhh....
As you can see, all my guesses at how to pass the enumerated string fail.
Before you flame me...
- I know that I could use another language (ruby, python, cocoa) to do this but that would require translating the rest of the code.
- I might be able to use CamelBones, but I don't want to assume my users have it installed.
- I could also use the NSAppleScript framework (assuming I went to the trouble of finding the Tab and Window IDs) but it seems odd to have to resort to it for just this one call.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
enum
不命名字符串常量;它命名为int
常量。这些名称中的每一个都是一个int
值。因此,请尝试打包为
a
或I
。或者,同时执行这两种操作:打包为a
,然后解包为I
并传递该数字。enum
does not name string constants; it namesint
constants. Each of these names is of anint
value.So, try packing as
a
orI
instead. Or, do both: Pack asa
, then unpack asI
and pass that number.