如何使用Perl的OS-X ScriptingBridge框架关闭窗口?

时间:2010-04-12 08:44:28

标签: cocoa perl macos applescript scripting-bridge

问题...

MacPerl is no longer supported on 64bit perl开始,我正在尝试使用其他框架来控制Terminal.app。

我正在尝试ScriptingBridge,但是在使用PerlObjCBridge将枚举字符串传递给closeSaving方法时遇到了问题。

我想打电话:

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框架(假设我遇到了查找Tab和Window ID的麻烦),但是只需要这一次调用就不得不诉诸它。

1 个答案:

答案 0 :(得分:2)

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;

enum没有命名字符串常量;它命名int常量。这些名称中的每一个都具有int值。

因此,请尝试打包为aI。或者,同时执行以下操作:打包为a,然后解压缩为I并传递该号码。