如何排除锁定的文件或文件夹在AppleScript中选择特定文件夹中的所有文件


4

这是我的情况。我创建了一个用于清理桌面的AppleScript。它实际上选择了我桌面上的所有文件和文件夹,创建了一个具有特定名称和日期格式的新文件夹,并将所有文件从我的桌面移动到新文件夹。这个脚本运行得很漂亮,直到我意识到偶尔会有我希望保留在桌面上的文件或文件夹。我的解决方案是打开我希望保留在桌面上的每个文件或文件夹的获取信息窗口,并在获取信息窗口中选择“锁定”选项。

我的问题现在是因为锁定的文件,脚本无法完全执行而不显示错误消息。如果我在错误消息上单击“确定”,脚本将完成并移动每个文件,但锁定的文件除外。

我宁愿不必通过单击“okay”按钮来完成这一额外步骤。我尝试将一些系统事件操作添加到脚本中以自动单击“确定”按钮,但这不起作用。

我开始认为唯一真正的解决方案是首先不选择那些锁定的文件或文件夹。这是我迷失的地方。任何人都可以帮我指导如何避免首先选择锁定的文件?

enter image description here


这是完整的脚本。


set scriptPath to (load script file "Macintosh HD:Users:Smokestack:Library:Mobile Documents:com~apple~ScriptEditor2:Documents:Cleanup Desktop.scptd:Contents:Resources:Scripts:Current Time A.M. P.M. And Short Date.scpt")

tell scriptPath
    timeandDate() -- This will get the time and date in this format "05/31/2017 @ 9:10:48 PM" called from the loaded script file above
end tell

set timeandDate to the result -- This will copy the time and date results from the previous step and and set it as this new variable

tell application "Finder"
    if running then
        close every window
        activate
        make new Finder window
        set target of Finder window 1 to folder "Desktop" of folder "Smokestack" of folder "Users" of startup disk
    end if
    open Finder window 1
    activate
end tell

delay 1
tell application "System Events"
    key code 0 using (command down) -- This will select all files and folders on the desktop in the active finder window
end tell

tell application "Finder"
    set these_items to the selection
    set destinationFolder to make new folder at POSIX file "/Users/Smokestack/Jimz_Important_Stuff/Desktop_Cleanups/" with properties {name:timeandDate}
    move these_items to destinationFolder
    reveal destinationFolder
end tell

这是脚本的修订版本,无需从外部文件调用处理程序

on timeandDate()
    set CurrentTime to (time string of (current date))
    set AppleScript's text item delimiters to ","
    set theLongDate to (current date)
    set theLongDate to (date string of theLongDate)
    set currentMonth to (word 1 of text item 2 of theLongDate)
    set currentDay to (word 2 of text item 2 of theLongDate)
    set currentYear to (word 1 of text item 3 of theLongDate)
    set monthList to {January, February, March, April, May, June, July, August, September, October, November, December}
    repeat with x from 1 to 12
        if currentMonth = ((item x of monthList) as string) then
            set theRequestNumber to (text -2 thru -1 of ("0" & x))
            exit repeat
        end if
    end repeat
    set currentMonth to theRequestNumber
    set currentDay to (text -2 thru -1 of ("0" & currentDay))
    set theShortDate to (currentMonth & "/" & currentDay & "/" & currentYear) as string
    set CurrentTime to (time string of (current date))
    set CurrentTimeandShortDate to (theShortDate & " @ " & CurrentTime)
    set AppleScript's text item delimiters to ""
end timeandDate

timeandDate()

set timeandDate to the result

tell application "Finder"
    close every window
    activate
    make new Finder window
    set target of Finder window 1 to folder "Desktop" of folder "Smokestack" of folder "Users" of startup disk
    select every file of the front Finder window 
    delay 1
    set these_items to the selection
    set destinationFolder to make new folder at POSIX file "/Users/Smokestack/Jimz_Important_Stuff/Desktop_Cleanups/" with properties {name:timeandDate}
    try
        move these_items to destinationFolder
    end try
    reveal destinationFolder
end tell

在对脚本进行一些修改之后,只要桌面上锁定的项目只是文件夹而不是文件,现在这个脚本就能很好地工作。但是,如果存在任何单独的锁定文件,它仍会生成错误。


感谢您的见解。您的Finder评论非常好点,我将在脚本中进行更改。谢谢
wch1zpink

是否有一种方法可以使用更短的命令...告诉应用程序“Finder”将选择设置为属性等于{locked:false}的每个文件< -----我试过大约20不同的变化没有成功
wch1zpink

所以我应该将set AppleScript的文本项分隔符添加到“”在timeandDate()处理程序的末尾,就在结束timeandDate之前?或者,在我调用处理程序后,是否将其添加到脚本本身的主体中?
wch1zpink


1
我已经更新了我的答案,希望你测试新的 并建议你使用它比另一个例子
user3439894

Answers:


4

更新: 正如我在评论中提到的那样,我在上周末建立了一个10.12.5系统并进行了一些测试,我做到了。

这是我发现的:

  • 我的答案的代码,包括6月2日15:34的编辑5,在我的系统上运行没有问题。
  • 经过全面审查 和评论,我突然意识到,虽然我的 ,因为,在我的系统上工作,我给出了引用的注释 delay 命令 不得不调整 和/或在必要时添加/删除等, 这主要归结为时间问题和特定形式的事件编码的缺陷。

因此,虽然我将在本更新的底部留下原始答案,但我决定从不同的程序角度来看这个,并提供以下内容 作为一种更好的编码方式 脚本 完成手头的任务。

这个新的 ,不依靠关闭开放 发现者 视窗 然后打开一个 发现者 窗口 到了 桌面 用户 然后有 系统事件 全选 项目 在里面 目标文件夹 ,或使用 delay 命令 处理时间问题等所有这些我个人不喜欢,因为我不想要所有 发现者 视窗 我已经打开,关闭以完成这样的任务。或者编码以留下现有的 视窗 打开,同时确保 发现者 窗口 桌面 在...内 是个 最高的 发现者 窗口 确保 系统事件 选择 正确的 项目 并获得正确的时间等!

下列 AppleScript的 提供了一种更安全,更快捷的方式来完成手头的任务,我鼓励您使用它 例子。

注意:使用之前的警告,(存在创建目标文件夹的文件夹等),您不应该需要修改此 并且应该能够使用它 原样 。也就是说,你当然可以自由修改 无论如何你需要/想要,但是 原样 ,它应该工作。

新的AppleScript

tell current application
    try
        tell application "Finder"
            if running then
                set theseFileSystemObjects to (get every item of (path to desktop))
                set theFileSystemObjectsNotLocked to {}
                repeat with i from 1 to (count of theseFileSystemObjects)
                    set thisFileSystemObject to (item i of theseFileSystemObjects)
                    if not locked of (get properties of thisFileSystemObject) then
                        set end of theFileSystemObjectsNotLocked to thisFileSystemObject
                    end if
                end repeat
                if theFileSystemObjectsNotLocked is not equal to {} then
                    tell current application to set theDateTimeNow to ¬
                        (do shell script "date '+%m.%d.%Y @ %I.%M.%S %p'") as string
                    set theDestinationFolder to make new folder at ¬
                        ((path to home folder as string) & "Jimz_Important_Stuff:Desktop_Cleanups:") with properties {name:theDateTimeNow}
                    move theFileSystemObjectsNotLocked to theDestinationFolder
                    open theDestinationFolder
                    activate theDestinationFolder
                end if
            else
                tell current application
                    activate
                    display dialog "Finder is not currently running!" & linefeed & linefeed & ¬
                        "Open Finder, then run Desktop Clean Up again." buttons {"OK"} ¬
                        default button 1 with title "Desktop Clean Up"
                end tell
            end if
        end tell
    on error eStr number eNum
        activate
        display dialog eStr & " number " & eNum buttons {"OK"} ¬
            default button 1 with title "Desktop Clean Up" with icon caution
        return
    end try
end tell

原答案:

这是我如何写整个的一个例子 脚本 成为 ,就像是一个 .scpt 文件或 的.app 文件,在您的系统上。我是说 你的系统 ,因为 目标目标文件夹 已为您的系统设置。

没有必要 加载 一个 外部资源 和不 处理器 变量 用于 目标文件夹名称 。我选择使用 do shell script 命令 为此,使用 date 命令 返回一个 自定义日期时间字符串变量 ,因为它是一行 相比之下 在里面 on timeandDate() 处理器 ,它返回相同的 图案

我会继续在我的系统上使用这个,并使用适当调整的路径名和不同的路径名 图案 对于 目标文件夹名称 ,取代 /:. 在里面 自定义日期时间字符串变量 用于 目标文件夹名称

作为编码,这是第一版 脚本 全部移动 文件系统对象 那是 锁定,目前在 桌面文件夹 到了 目标文件夹 。该 脚本 包括最小的适当 错误处理 如编码,你不应该有你以前遇到的问题。这当然假设了 $HOME/Jimz_Important_Stuff/Desktop_Cleanups 文件夹存在。如果没有,您将收到相应的错误消息,无论如何 错误处理 可以添加以在必要时创建分层折叠结构。

这第一个 脚本 应该解决你自己的所有问题 和IMO是一种更好的方式来编码它然后只是陷阱和吃错误 try 声明 单独,因为编码时,它只能移动文件 已锁定,甚至没有尝试移动锁定的文件。

这是在macOS 10.12.3下测试的,应该适用于你目前正在运行的macOS 10.12.5。

AppleScript的


tell current application
    try
        set theDateTimeNow to (do shell script "date '+%m/%d/%Y @ %I:%M:%S %p'") as string
        tell application "Finder"
            if running then
                close every window
                set target of (make new Finder window) to (path to desktop)
                activate
                delay 0.5
                tell application "System Events" to key code 0 using {command down}
                delay 0.5
                set theseFileSystemObjects to the selection
                set theDestinationFolder to make new folder at ¬
                    ((path to home folder as string) & "Jimz_Important_Stuff:Desktop_Cleanups:") with properties {name:theDateTimeNow}
                set theListOfFileSystemObjectsNotLocked to {}
                repeat with i from 1 to (count of theseFileSystemObjects)
                    set thisFileSystemObject to (item i of theseFileSystemObjects)
                    if not locked of thisFileSystemObject then
                        set end of theListOfFileSystemObjectsNotLocked to thisFileSystemObject
                    end if
                end repeat
                move theListOfFileSystemObjectsNotLocked to theDestinationFolder
                reveal theDestinationFolder
            else
                tell current application
                    activate
                    display dialog "Finder is not currently running!" & linefeed & linefeed & ¬
                        "Open Finder, then run Desktop Clean Up again." buttons {"OK"} ¬
                        default button 1 with title "Desktop Clean Up" with icon caution
                end tell
            end if
        end tell
    on error eStr number eNum
        activate
        display dialog eStr & " number " & eNum buttons {"OK"} ¬
            default button 1 with title "Desktop Clean Up" with icon caution
        return
    end try
end tell

注意:至于 delay 命令 ,它们可能需要针对您的系统进行调整,或者根据需要进行额外调整,或者在不需要时进行调整。如目前编码,这 脚本 毫无问题地工作,在我的系统上进行了数十次测试,具有不同的数量和大小 文件系统对象 被采取行动 桌面文件夹 。根据需要进行任何调整。

文件系统对象 测试过, 文件夹 别名 符号链接 应用程序包 文件包 ,后两者只是 文件夹 。这些FSO具有各种尺寸,包括锁定和 锁定。


这个第二版 脚本 超出了你所表达的需求,并复制了锁定的 文件系统对象 目前在 桌面文件夹 到了 目标文件夹 ,同时重置重复项上的锁定标志,以便在您可以选择删除它们时不删除标记就可以删除它们。我包括它,因为它可能增加了价值,你发现它很有用。

AppleScript的


tell current application
    try
        set theDateTimeNow to (do shell script "date '+%m/%d/%Y @ %I:%M:%S %p'") as string
        tell application "Finder"
            if running then
                close every window
                set target of (make new Finder window) to (path to desktop)
                activate
                delay 0.5
                tell application "System Events" to key code 0 using {command down}
                delay 0.5
                set theseFileSystemObjects to the selection
                set theDestinationFolder to make new folder at ¬
                    ((path to home folder as string) & "Jimz_Important_Stuff:Desktop_Cleanups:") with properties {name:theDateTimeNow}
                set theListOfFileSystemObjectsNotLocked to {}
                set theListOfLockedFileSystemObjects to {}
                repeat with i from 1 to (count of theseFileSystemObjects)
                    set thisFileSystemObject to (item i of theseFileSystemObjects)
                    if not locked of thisFileSystemObject then
                        set end of theListOfFileSystemObjectsNotLocked to thisFileSystemObject
                    else
                        set end of theListOfLockedFileSystemObjects to thisFileSystemObject
                    end if
                end repeat
                move theListOfFileSystemObjectsNotLocked to theDestinationFolder
                duplicate theListOfLockedFileSystemObjects to theDestinationFolder
                repeat with i from 1 to (count of theListOfLockedFileSystemObjects)
                    set thisFileSystemObject to (item i of theListOfLockedFileSystemObjects)
                    set locked of alias ((theDestinationFolder as string) & name of thisFileSystemObject) to false
                end repeat
                reveal theDestinationFolder
            else
                tell current application
                    activate
                    display dialog "Finder is not currently running!" & linefeed & linefeed & ¬
                        "Open Finder, then run Desktop Clean Up again." buttons {"OK"} ¬
                        default button 1 with title "Desktop Clean Up" with icon caution
                end tell
            end if
        end tell
    on error eStr number eNum
        activate
        display dialog eStr & " number " & eNum buttons {"OK"} ¬
            default button 1 with title "Desktop Clean Up" with icon caution
        return
    end try
end tell

好吧,我运行了你的脚本的第一个版本几次,每次和脚本编辑,它抛出一个错误消息告诉应用程序“脚本编辑器”显示对话框“文件夹”“无法移动到自身。数字-122”按钮{“确定“}图标警告的默认按钮1 - > {按钮返回:“确定”}结束告诉
wch1zpink

运行第二个版本的脚本我得到了相同的错误消息...我想它可能是因为在我的桌面上我已经安装了Macintosh HD,Boot Camp和两个单独的时间胶囊。一旦脚本抛出错误,我会查看我的桌面并选择每个项目,包括那些已安装的驱动器
wch1zpink

在finder首选项中,我选择不在桌面上显示那些已安装的驱动器,然后我运行了脚本,它运行得很漂亮。如果你能找到一种方法来排除在脚本中选择已安装的驱动器,那么你将是一个疯狂的天才LOL
wch1zpink

@ wch1zpink,如果第一个愿景有问题,第二个版本不会修复它。如果没有看到完整的日志,那么诊断问题将会更加困难。我会说替换的测试 /:. 在里面 do shell script "date ..." 命令 ,以避免命名约定中的任何问题。而且,看到输出会很好 ls -al@ "$HOME/Desktop/" 设备显示。已安装的设备虽然出现在人机界面的桌面上,但它们并不存在 $HOME/Desktop 文件夹,这应该与脚本的功能无关!
user3439894

1
@ wch1zpink,显然我的系统和你的系统之间有一些不同的东西,但是什么!?本周末我将尝试花时间设置一个10.12.5系统,看看我是否可以重现这个问题。解决方法选项可能是以编程方式,如果可能,切换显示/隐藏外部设备的标志...,移动目标文件,并再次切换标志。 (也就是说,如果你总是展示那些设备。)我会看一下,但我希望能够重现你的问题,然后适当地为它编码而不是解决方法。
user3439894

3

我的方法是将一些代码放入 try 阻止也使用 on error 忽略该特定错误消息,但如果遇到其他错误,仍然显示消息。

这种方法的优点是你不会告诉你的脚本忽略所有错误,以防其他事情发生,你应该知道它。

为了实现这一目标,请尝试以下方法:

set scriptPath to (load script file "Macintosh HD:Users:Smokestack:Library:Mobile Documents:com~apple~ScriptEditor2:Documents:Cleanup Desktop.scptd:Contents:Resources:Scripts:Current Time A.M. P.M. And Short Date.scpt")

tell scriptPath
    timeandDate() -- This will get the time and date in this format "05/31/2017 @ 9:10:48 PM" called from the loaded script file above
end tell

set timeandDate to the result -- This will copy the time and date results from the previous step and and set it as this new variable

tell application "Finder"
    if running then
        close every window
        activate
        make new Finder window
        set target of Finder window 1 to folder "Desktop" of folder "Smokestack" of folder "Users" of startup disk
    end if
    open Finder window 1
    activate
end tell

delay 1
tell application "System Events"
    key code 0 using (command down) -- This will select all files and folders on the desktop in the active finder window
end tell

tell application "Finder"
    try
        set these_items to the selection
        set destinationFolder to make new folder at POSIX file "/Users/Smokestack/Jimz_Important_Stuff/Desktop_Cleanups/" with properties {name:timeandDate}
        move these_items to destinationFolder
        reveal destinationFolder
    on error error_message number error_number
        if the error_number is not -50 then
            display dialog error_message buttons {"OK"} default button 1
        end if
    end try

end tell

现在,你会看到我放置了第二块 tell application "Finder" 一个代码 try 阻止(你会注意到使用 tryend try。并且,在该块中我插入了以下代码:

    on error error_message number error_number
    if the error_number is not -50 then
        display dialog error_message buttons {"OK"} default button 1
    end if

基本上,这个 应该 具有告诉脚本在发生Finder错误-50时忽略它的效果,但如果它不是-50则显示错误。 (我假设这是你的脚本得到的错误 - 如果不是你可以只替换 -50 使用正确的错误号。

显然我不能在最后测试这个,所以请让我知道你怎么做。


我无法复制wch1zpink的确切错误消息,但我同意您的回答...使用适当的错误处理。 +1
user3439894

@Monomeeth我运行了你的代码版本并将其保存为应用程序,它产生了完全相同的错误消息
wch1zpink
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.