使用JXA AppleScript获取活动查找器窗口的POSIX路径

使用JXA AppleScript获取活动查找器窗口的POSIX路径,applescript,macos-sierra,finder,javascript-automation,Applescript,Macos Sierra,Finder,Javascript Automation,我想要这个AppleScript片段的JXA等价物: 告诉应用程序“Finder” #获取路径 将currentTarget设置为窗口1的目标 将posixPath设置为(POSIX路径为(currentTarget作为别名)) #显示对话框 显示对话框posixPath按钮{“确定”} 结束语 我得到的最接近的方法是使用url属性初始化对象并访问其属性,如下所示: //获取路径 var finder=应用程序('finder') var currentTarget=finder.finder

我想要这个AppleScript片段的JXA等价物:

告诉应用程序“Finder”
#获取路径
将currentTarget设置为窗口1的目标
将posixPath设置为(POSIX路径为(currentTarget作为别名))
#显示对话框
显示对话框posixPath按钮{“确定”}
结束语
我得到的最接近的方法是使用
url
属性初始化对象并访问其属性,如下所示:

//获取路径
var finder=应用程序('finder')
var currentTarget=finder.finderWindows[0].target()
var fileURLString=currentTarget.url()
//我想摆脱这一步
var fileURL=$.NSURL.alloc.initWithString(fileURLString)
var posixPath=fileURL.fileSystemRepresentation
//显示对话框
finder.includeStandardAdditions=真
displayAlert(“”,{按钮:['Ok'],消息:posixPath})
但这似乎不必要地复杂。在不使用Fund API < /String >还是手动字符串冲突的情况下,有强到更好的方式到POSIX路径<强>?

如果我天真地尝试这一点:

finder.finderWindows[0].target().posixPath()
我得到这个错误:

app.startupDisk.folders.byName(“用户”).folders.byName(“kymer”).folders.byName(“桌面”).posixPath()
-->错误-1728:无法获取对象。
这似乎很相关,但我似乎无法调整它以满足我的需要:

App=Application.currentApplication()
App.includeStandardAdditions=真
SystemEvents=应用程序(“系统事件”)
var pathToMe=App.pathTo(此)
var containerPOSIXPath=SystemEvents.files[pathToMe.toString()].container().posixPath()
任何帮助都将不胜感激

@Kymer,你说:

但这似乎不必要地复杂。有没有更好的办法去 没有使用Cocoa API或手动字符串争用的POSIX路径

你在正确的轨道上。这是我所知道的最好的方法。如果有更好的,我也想知道。但是,这似乎工作得很快,对文件和文件夹都有效

var finderApp=应用程序(“查找器”);
var itemList=finderApp.selection();
var oItem=itemList[0];
var oItemPaths=getPathInfo(oItem);
/*---oItemPaths对象键---
oItemPaths.itemClass
全速前进
oItemPaths.parentPath
oItemPaths.itemName
*/
log(JSON.stringify(oItemPaths,未定义,4))
函数getPathInfo(pFinderItem){
var itemClass=pFinderItem.class();//如果项是文件夹,则返回“folder”。
var itemURL=pFinderItem.url();
var fullPath=decodeURI(itemURL).slice(7);
//---删除尾随“/”以处理文件夹项(如果有)---
var pathElem=fullPath.replace(/\/$/,“”)。split(“/”)
var itemName=pathElem.pop();
var parentPath=pathElem.join('/');
返回{
itemClass:itemClass,
完整路径:完整路径,
父路径:父路径,
itemName:itemName
};
}

理论上,您可以编写如下内容:

finder.finderWindows[0].target({as:"alias"})
但这不起作用,文档中也没有任何内容表明它受支持。但这是JXA的SOP,与苹果早期的脚本桥一样,JXA也存在许多设计缺陷和遗漏,这些缺陷和遗漏从未(也可能永远不会)修复

FWIW,下面是如何在Node.js中使用以下命令执行此操作:

(请注意,NodeAutomation对我来说是一个非常低优先级的项目,因为Mac Automation在苹果公司看来几乎处于最后阶段。请注意emptor等。对于非琐碎的脚本编写,我强烈建议坚持使用AppleScript,因为它是唯一一个真正正常工作的官方支持的解决方案。)



[1] 例如,JXA的另一个限制是,大多数应用程序的
move
duplicate
命令严重受损,因为JXA作者忘记了实现。(顺便说一句,我在JXA发布之前就报告了所有这些问题,而appscript在十年前就解决了所有这些问题,所以他们也没有理由不把它做好。)

这里有一个相当简单的示例函数,它只需抓取窗口的
目标
,然后从其
url
中去掉前面的
文件://

/*
pathToFrontWindow()
returns path to front Finder window
*/
function pathToFrontWindow() {
    if ( finder.windows.length ) {
        return decodeURI( finder.windows[0].target().url().slice(7) )
    } else {
        return ""
    }
}

这样一段简单的AppleScript代码没有直接的JXA翻译,这一事实证明了基于OSA脚本的JXA和macOS自动化的糟糕状态

  • 包含有用的背景信息

  • 另一个要点是(在撰写本文时,我们即将发布macOS 10.13(High Sierra)

  • 更广泛地宣布“上个月在WWDC上终于回答了这个问题:苹果放弃了它的自动化技术,任由它们枯萎和消亡。

正如您自己的示例所示,在两种即将消亡的自动化脚本语言中,AppleScript(尽管有很多缺点)是更成熟、更可靠的选择


为了解决JXA中的问题,看起来您自己已经想出了最好的方法。 让我把它打包成一个辅助函数,也许可以减轻一些痛苦——说得清楚一点:这样的辅助函数不应该是必要的:

//Helper函数:给定Finder窗口,返回其文件夹的POSIX路径。
//注意:不需要ObjC.import()语句,因为NSURL是
//基础类,所有基础类都是隐式的。
//可用。
函数posixPath(finderWin){
返回$.NSURL.alloc.initWithString(finderWin.target.url()).fileSystemRepresentation
}
//获取Finder最前面窗口的POSIX路径:
posixPath(应用程序('Finder')。finderWindows[0])

Cocoa API有什么问题?它比发送Apple事件快得多。@vadian:这是一个简单的脚本任务,应该有一个简单的JXA专用解决方案,类似于(合理地)简单的AppleScript专用解决方案。要求编剧
/*
pathToFrontWindow()
returns path to front Finder window
*/
function pathToFrontWindow() {
    if ( finder.windows.length ) {
        return decodeURI( finder.windows[0].target().url().slice(7) )
    } else {
        return ""
    }
}
(() => {

    // getFinderDirectory :: () -> String
    const getFinderDirectory = () =>
        Application('Finder')
        .insertionLocation()
        .url()
        .slice(7);

    return getFinderDirectory();
})();