1

我一直在尝试创建一个脚本,该脚本将生成所有可用服务名称的 XML 结构。它在脚本编辑器中运行良好,但不能从命令行运行。我的代码是:

ObjC.import("Cocoa");
ObjC.import("AppKit");


function run(arg) {
    items = $.NSApp.servicesMenu.itemArray;

    list = "<items>";
    count = 0;
    items.enumerateObjectsUsingBlock(function( obj, index, stop ){
        list += "<item uid='Service" + count + "' arg='" + obj.title.UTF8String + "' valid='yes' autocomplete='"  + obj.title.UTF8String + "'><title>" + obj.title.UTF8String + "</title><subtitle>Services Toolbox</subtitle><icon>icon.png</icon></item>";
        count++;
    });

    list += "</items>";

    return list;
}

此代码将在 Alfred 工作流程中使用。关于如何改变它的任何想法?

据我所知,在 osascript 解释器中运行它没有服务菜单,但脚本编辑器有。我怎样才能解决这个问题以获取服务列表?

4

1 回答 1

0

你是对的,因为脚本是通过 启动的osascript$.NSApp所以无法访问服务菜单。

但是,通过一些 UI 脚本,您可以通过 finder 应用程序找到所有菜单项:

function grabFirstNested(arr) {
  if (arr.length <= 0 || !Array.isArray(arr[0])) {
    return arr;
  }

  return grabFirstNested(arr[0]);
}

function run(arg) {

  var sys = Application('System Events');

  var servicesRef = sys.processes['Finder'].menuBars.menuBarItems.whose({
    name: { _contains: 'finder'}
  }, {ignorign: 'case'}).menus.menuItems.whose({
    name: { _contains: 'services'}
  }, {ignoring: 'case'}).menus.menuItems.name;

  var services = grabFirstNested(servicesRef());
  var list = "<items>";
  services.forEach(function(service, index) {
    list += "<item uid='Service" + index + "' arg='" + service + "' valid='yes' autocomplete='"  + service + "'><title>" + service + "</title><subtitle>Services Toolbox</subtitle><icon>icon.png</icon></item>";
  });
  list += "</items>";

  return list;
}

该脚本将通过System EventsAPI 访问 Finder 应用程序,这些 API 可以访问用于编写脚本的 UI 元素。一旦有了 Finder 应用程序,它就会MenuItems从“服务”菜单栏项中获取。

于 2014-11-20T05:35:33.713 回答