1

我正在使用以下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
谁能帮帮我?

4

2 回答 2

4

如果您使用 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];
    }
}
于 2012-04-19T11:21:47.043 回答
4

这是一个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'
于 2012-04-19T15:03:27.157 回答