我一直在尝试创建一个脚本,该脚本将生成所有可用服务名称的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 Workflow。关于如何改变它的任何想法?
据我所知,在osascript解释器中运行它没有“服务”菜单,但脚本编辑器可以。我怎样才能解决这个问题以获得服务列表?
答案 0 :(得分: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 Events
API访问Finder应用程序,这些API可访问用于编写脚本的UI元素。一旦有了Finder应用程序,它就会从&#34;服务&#34;中获取MenuItems
。菜单栏项目。