[英]Listing all the files in a folder using JavaScript for Automation on Yosemite
我正在嘗試將一些舊的Applescript移植到新的JavaScript語法中。
事情似乎非常直接,所以:
tell application "System Events" to keystroke "t" using command down
成為:
System = Application('System Events');
System.keystroke("t", {using: "command down"})
但是我不能為我的生活找出如何列出特定位置的文件。 在AppleScript中,要返回/usr
目錄中的文件列表,您可以:
tell application "System Events" to set fileList to name of items in folder "/usr"
-- > {"bin", "include", "lib", "libexec", "local", "sbin", "share", "standalone", "X11"}
但是我不能為我的生活弄清楚如何在Javascript中做到這一點。
System = Application('System Events')
myPath = Path("/usr")
fileList = System.items(myPath)
-- > message not understood
fileList = System.folder(myPath)
-- > message not understood
fileList = System.diskItems(myPath)
-- > []
fileList = System.diskItems({at:myPath)
-- > []
我也嘗試了很多其他組合,但沒有運氣。 有任何想法嗎?
就像Leopard的Scripting Bridge之前一樣,JXA故意打破各種在AppleScript中完美運行的東西。 以下是原始AppleScript命令到JXA語法的轉換:
//tell application "System Events" to name of items in folder "/usr"
Application('System Events').folders.byName('/usr').items.name()
AS版本運行完美,但JXA等效只是拋出一個完全沒有意義的Error -1700: Can't convert types.
如果您編寫diskItems
而不是items
JXA似乎確實有效:
Application('System Events').folders.byName('/usr').diskItems.name()
// --> ["bin", "lib", "libexec", "local", "sbin", "share", "standalone", "X11", "X11R6"]
這表明JXA沉迷於同樣的內部“聰明”,導致SB打破這么多的應用程序。 (請注意,我在早期的測試中發現了許多這樣的設計缺陷,但是一旦很明顯AS開發人員只關心強加他們自己的個人意識形態和對其他人的偏見,殘缺的能力和破壞的兼容性被詛咒就放棄了。)
為了比較,這里是JavaScriptOSA(JOSA)原型我幾個月前很快就為JXA開發人員的參考組合在一起(他們很快忽略了它,natch):
app('System Events').folders.named('/usr').items.name()
// -> ["bin", "lib", "libexec", "local", "sbin", "share", "standalone", "X11", "X11R6"]
(雖然沒有完全完成或測試,但JOSA仍然比JXA更好看,更好地記錄,甚至包括一個自動翻譯工具,用於將AS命令轉換為JS語法。不幸的是,因為Apple已經刪除或棄用了AEM,CM ,PM和OSA Carbon API,我不推薦它用於生產用途;它純粹用於比較目的。)
同理:
set myPath to POSIX file "/usr"
tell application "System Events" to name of every disk item of folder named myPath
--> {"bin", "lib", "libexec", "local", "sbin", "share", "standalone", "X11", "X11R6"}
myPath = Path('/usr')
Application('System Events').folders.byName(myPath).diskItems.name()
// Error -1728: Can't get object.
var myPath = Path('/usr')
app('System Events').folders.named(myPath).diskItems.name()
// --> ["bin", "lib", "libexec", "local", "sbin", "share", "standalone", "X11", "X11R6"]
您可以通過將Path對象轉換為字符串來解決該特定情況,並使用它:
myPath = Path('/usr')
Application('System Events').folders.byName(myPath.toString()).diskItems.name()
雖然這種解決方法在其他情況下不一定有用; 例如,它在Finder中失敗,因為Finder不理解POSIX樣式的路徑字符串,並且無法從JXA Path對象獲取HFS樣式的路徑字符串(Finder確實理解):
set myPath to POSIX file "/usr"
tell application "Finder" to name of every item of item myPath
--> {"X11", "X11R6", "bin", "lib", "libexec", "local", "sbin", "share", "standalone"}
myPath = Path('/usr')
Application('Finder').folders.byName(myPath.toString()).items.name()
// Error -1728: Can't get object.
它就這樣了。 (例如,嘗試測試JXA對范圍,過濾器,相對和插入參考形式的支持 ;它特別腐爛。)
"System Events"
方法確實具有簡單性的優點,但事實證明使用$.NSFileManager
(現在可直接用於腳本編寫)可以顯着提高性能。
在我的系統上,開始與之比較
var strPath = '/usr';
var appSys = Application('System Events'),
lstHarvest = appSys.folders.byName(strPath).diskItems.name();
幾千次迭代的快速測試表明,通過這種略微巴洛克式的方法,我們可以通過適度的40%加速它:
var strPath = '/usr';
var fm = $.NSFileManager.defaultManager,
oURL = $.NSURL.fileURLWithPathIsDirectory(strPath, true),
lstFiles = ObjC.unwrap(
fm.contentsOfDirectoryAtURLIncludingPropertiesForKeysOptionsError(
oURL, [], 1 << 2, null
)
),
lstHarvest = [];
lstFiles.forEach(function (oItem) {
lstHarvest.push(
ObjC.unwrap(oItem.path)
);
});
而且相當簡單,超過300%:
var strPath = '/usr';
var fm = $.NSFileManager.defaultManager,
lstFiles = ObjC.unwrap(
fm.contentsOfDirectoryAtPathError(strPath, null)
),
lstHarvest = [];
lstFiles.forEach(function (oItem) {
lstHarvest.push(
ObjC.unwrap(oItem)
);
});
我可以這樣得到它
foldersList = foldersList = System.folders.byName("usr").folders.name()
- > [“bin”,“lib”,“libexec”,“sbin”,“share”,“standalone”,“X11”]
甚至這個工作:
foldersList = System.folders.byName("/Users/USERName/Documents/").folders.name()
但我到目前為止無法獲得Path命令來處理除“打開”之外的任何事情
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.