【问题标题】:How to relaunch finder application如何重新启动查找器应用程序
【发布时间】:2012-04-19 09:27:03
【问题描述】:

我正在使用以下applescript 重新启动查找器应用程序。

osascript -e "tell application \"Finder\"" -e "delay 1" -e "try" -e "quit" -e "delay 1" -e "activate" -e "end try" -e "end tell"  

但有时此脚本不会重新启动 finder 应用程序(仅退出 finder 应用程序)。我在控制台中没有收到任何错误。
http://www.cocoabuilder.com/archive/cocoa/113654-nsapplescript-buggy.html
谁能帮帮我?

【问题讨论】:

    标签: objective-c applescript finder appleevents


    【解决方案1】:

    这是一个applescript方式。如您所见,您不能依赖特定的延迟时间。因此,我们通过检查它是否在正在运行的进程列表中来手动等待 Finder 退出。当它不再在列表中时,我们知道它已经退出,我们可以再次激活它。

    您还会注意到,由于重复循环,我在脚本中添加了时间检查。万一出现问题,我们不希望重复循环永远运行。因此,如果它运行超过 10 秒,我们会自动退出重复循环。

    tell application "Finder" to quit
    
    set inTime to current date
    repeat
        tell application "System Events"
            if "Finder" is not in (get name of processes) then exit repeat
        end tell
        if (current date) - inTime is greater than 10 then exit repeat
        delay 0.2
    end repeat
    
    tell application "Finder" to activate
    

    这是该代码的 osascript 版本。

    /usr/bin/osascript -e 'tell application "Finder" to quit' -e 'set inTime to current date' -e 'repeat' -e 'tell application "System Events"' -e 'if "Finder" is not in (get name of processes) then exit repeat' -e 'end tell' -e 'if (current date) - inTime is greater than 10 then exit repeat' -e 'delay 0.2' -e 'end repeat' -e 'tell application "Finder" to activate'
    

    【讨论】:

    • 告诉应用程序“Finder”后需要延迟以防止随机的“连接无效 -609”AppleScript 错误??
    • 根据我的经验,随机错误是通过在 Finder 退出前过早重启而产生的。所以我们使用系统事件等待它退出以防止此类问题。无论如何,我的重复循环有一个延迟,以防止您描述的内容。我相信这个理论是正确的。
    • 退出前是否需要延迟?
    • 如果您真的想确定,您可以使用该方法检查 Finder 是否仍在运行。如果 Finder 在 5 秒后(或您认为合适的任何时间)仍在运行,则重新发出 quit 命令。在任何一种情况下,使用系统事件来检查 Finder 是否运行都是有意义的。
    • 告诉应用程序“Finder”延迟 1 - 此延迟对于防止随机“连接无效 -609”AppleScript 错误很重要。我从总发现者那里得到了这个脚本
    【解决方案2】:

    如果您使用 Cocoa,这是错误的处理方式。您应该尽可能使用本机 API,而您正在尝试调用本身构建和运行 AppleScript 的 shell 脚本。您的 AppleScript 在尝试重新启动之前等待一秒钟,这是一个任意值。您实际上应该在等待 Finder 退出。

    相反,您应该使用 NSRunningApplication 类来管理它,通过使用 Key-Value Observing 来监控实例的 terminated 属性,以便您可以在应用终止时重新启动应用:

    //assume "finder" is an ivar of type NSRunningApplication
    //it has to be a strong reference or it will be released before the observation method
    //is called
    
    - (void)relaunchFinder
    {
        NSArray* apps = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.finder"];
        if([apps count])
        {
            finder = [apps objectAtIndex:0];
            [finder addObserver:self forKeyPath:@"isTerminated" options:0 context:@"QuitFinder"];
            [finder terminate];
        }
    
    }
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        if (context == @"QuitFinder")
        {
            if([keyPath isEqualToString:@"isTerminated"])
            {
                [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:@"com.apple.finder" options:NSWorkspaceLaunchDefault additionalEventParamDescriptor:NULL launchIdentifier:NULL];
                [object removeObserver:self forKeyPath:@"isTerminated"];
            }
        } else {
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }
    

    【讨论】:

    • 我在安装应用程序时使用我的脚本。
    • 那么为什么你的问题被标记为cocoa 并且你的链接指向一个 Cocoa 邮件列表?
    • Stiphane Sudre 也遇到了同样的问题。他正在使用 NSAppleScript 类执行 applescript,而我正在使用 osascript。
    • 对于可可应用,这是完美的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    相关资源
    最近更新 更多