2010-11-29 37 views
2

我写了一个AppleScript来安装SparseBundle图片,我希望它在Time Machine启动时正好执行。如何在Mac OS X中侦听应用程序启动事件?

现在,我定期检查时间机器被使用on idle声明AppleScript运行:

on idle 
    .... 
    return <interval> 
end idle 

这不是一个可靠的方法。在我看来,为Application Launch事件添加事件触发器将是更好的方法。

你能帮忙吗?

一个Objective-CPython示例代码(我更喜欢Python)是多余的欢迎。

回答

4

你所寻找的是,NSDistributedNotificationCenterNSWorkspace,这些可可类发布的应用程序事件,工作区,像应用程序启动的通知,安装驱动器等

的Python中做到这一点,你需要PyObjC,这基本上是苹果可可类的python绑定。这些文档在他们的网站上是稀少的,这是有原因的,因为文档基本上与Apple文档相同,所以它们只包括pyobjc api和cocoa API之间的区别。如果你了解目标c api如何转换为python,那么你很好。检查这里:http://pyobjc.sourceforge.net/documentation/pyobjc-core/intro.html

我已经包括一个例子,下面使用python侦听分布式通知。下面的代码基本上添加了一个观察者,并侦听iTunes通知。你可以遵循一个类似的结构,但是添加一个NSWorkspace的观察者。为了弄清楚你应该听什么,有一个应用程序将显示所有通过你的系统的通知。它被称为notification watcher。用它来确定你应该听的东西。您也可以将目标c代码转换为python。

什么下面的代码是做

  1. 定义一个新的类,从NSObject的继承,通过PyObjC
  2. 定义定义一个方法,它被传递的实际通知,并打印出来
  3. 创建Foundation.NSDistributedNotificationCenter的一个实例。defaultCenter
  4. 创建GetSongs的实例
  5. 注册一个观察者,向它传递类,当接收到通知时调用和该申请&事件来监视即“com.apple.iTunes.playerInfo”
  6. 该方法
  7. 运行事件循环,

一件事,会让你出错,访问属性(Objective C的属性)不工作一样访问蟒蛇属性。即在Python的Python为目标C做class_name.att你要称呼它从下面我举的例子,即一个功能:song.userInfo()

import Foundation 
from AppKit import * 
from PyObjCTools import AppHelper 

class GetSongs(NSObject): 
    def getMySongs_(self, song): 
     print "song:", song 
     song_details = {} 
     ui = song.userInfo() 
     print 'ui:', ui 
     for x in ui: 
      song_details[x] = ui.objectForKey_(x) 
     print song_details 

nc = Foundation.NSDistributedNotificationCenter.defaultCenter() 
GetSongs = GetSongs.new() 
nc.addObserver_selector_name_object_(GetSongs, 'getMySongs:', 'com.apple.iTunes.playerInfo',None) 

NSLog("Listening for new tunes....") 
AppHelper.runConsoleEventLoop() 

这里的实际输出的一个例子...(YES BRITNEY ROCKS!NOT !;)

song NSConcreteNotification 0x104c0a3b0 {name = com.apple.iTunes.playerInfo; object = com.apple.iTunes.player; userInfo = { 
    Album = Circus; 
    "Album Rating" = 0; 
    "Album Rating Computed" = 1; 
    Artist = "Britney Spears"; 
    "Artwork Count" = 1; 
    Genre = Pop; 
    "Library PersistentID" = 8361352612761174229; 
    Location = "file://localhost/Users/izze/Music/iTunes/iTunes%20Music/Britney%20Spears/Circus/02%20Circus.mp3"; 
    Name = Circus; 
    PersistentID = 4028778662306031905; 
    "Play Count" = 0; 
    "Play Date" = "2010-06-26 08:20:57 +0200"; 
    "Player State" = Playing; 
    "Playlist PersistentID" = 7784218291109903761; 
    "Rating Computed" = 1; 
    "Skip Count" = 1; 
    "Skip Date" = "2010-06-26 12:20:57 +0200"; 
    "Store URL" = "itms://itunes.com/link?n=Circus&an=Britney%20Spears&pn=Circus"; 
    "Total Time" = 192444; 
    "Track Count" = 16; 
    "Track Number" = 2; 
}} 
ui { 
    Album = Circus; 
    "Album Rating" = 0; 
    "Album Rating Computed" = 1; 
    Artist = "Britney Spears"; 
    "Artwork Count" = 1; 
    Genre = Pop; 
    "Library PersistentID" = 8361352612761174229; 
    Location = "file://localhost/Users/izze/Music/iTunes/iTunes%20Music/Britney%20Spears/Circus/02%20Circus.mp3"; 
    Name = Circus; 
    PersistentID = 4028778662306031905; 
    "Play Count" = 0; 
    "Play Date" = "2010-06-26 08:20:57 +0200"; 
    "Player State" = Playing; 
    "Playlist PersistentID" = 7784218291109903761; 
    "Rating Computed" = 1; 
    "Skip Count" = 1; 
    "Skip Date" = "2010-06-26 12:20:57 +0200"; 
    "Store URL" = "itms://itunes.com/link?n=Circus&an=Britney%20Spears&pn=Circus"; 
    "Total Time" = 192444; 
    "Track Count" = 16; 
    "Track Number" = 2; 
} 
{u'Album Rating Computed': 1, u'Album': u'Circus', u'Rating Computed': True, u'Name': u'Circus', u'Artist': u'Britney Spears', u'Track Number': 2, u'Skip Date': 2010-06-26 12:20:57 +0200, u'Library PersistentID': 8361352612761174229L, u'Player State': u'Playing', u'Total Time': 192444L, u'Genre': u'Pop', u'Playlist PersistentID': 7784218291109903761L, u'Album Rating': 0, u'Location': u'file://localhost/Users/izze/Music/iTunes/iTunes%20Music/Britney%20Spears/Circus/02%20Circus.mp3', u'Skip Count': 1, u'Track Count': 16L, u'Artwork Count': 1, u'Play Date': 2010-06-26 08:20:57 +0200, u'PersistentID': 4028778662306031905L, u'Play Count': 0, u'Store URL': u'itms://itunes.com/link?n=Circus&an=Britney%20Spears&pn=Circus'} 
3

这在Objc-C中不太难处理。您可以通过NSWorkspace和NSNotificationCenter访问所有应用程序的通知。创建一个对象并注册它的一个方法来通知NSWorkspaceDidTerminateApplicationNotification类型的通知。就像:

@interface NotificationObserver : NSObject { } 
- (void) applicationDidLaunch:(NSNotification*)notification; 
@end 

@implementation NotificationObserver : NSObject 
- (void) applicationDidLaunch:(NSNotification*)notification 
{ 
    // Check the notification to see if Time Machine is being launched. 
} 
@end 

void watch(void) 
{ 
    NSNotificationCenter* notificationCenter 
    = [[NSWorkspace sharedWorkspace] sharednotificationCenter]; 
    NotificationObserver* observer = [[NotificationObserver alloc] init]; 
    [notificationCenter addObserver:observer 
         selector:@selector(applicationDidTerminate:) 
          name:@"NSWorkspaceDidTerminateApplicationNotification" 
          object:nil]; 
} 
0

这不是你的问题的答案,但它可以解决你的问题。

为什么在安装磁盘映像后不要让AppleScript启动Time Machine?然后,不要直接启动Time Machine,始终通过脚本调用Time Machine。您甚至可以将Time Machine图标粘贴到您的AppleScript文件上,并将其命名为“Time Machine”,以使幻觉完成。 :-)

相关问题