2010-11-29 6 views
2

Я написал AppleScript, чтобы установить изображение SparseBundle, и я хочу, чтобы он выполнялся точно при запуске Time Machine.Как прослушать событие запуска приложения в Mac OS X?

Прямо сейчас, я периодически проверять, если Time Machine работает с AppleScript используя on idle заявление:

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

, который не является надежным способом. По-моему, добавление триггера события для события Application Launch будет лучшим подходом.

Не могли бы вы помочь?

Objective-C или Python образец кода (я бы предпочел Python) более чем приветствуется.

ответ

4

То, что вы ищете, NSDistributedNotificationCenter или NSWorkspace, эти классы какао отправлять уведомления о событиях приложения, Для рабочей области, такие вещи, как запуск приложений, установка приводов и т.д.

Чтобы сделать это в Python, вам нужен PyObjC, который в основном привязывает python к классам какао для Apple. Документация разрешена на их веб-сайте, и есть причина, поскольку документация будет в основном такой же, как документы Apple, поэтому они включают только различия между pyobjc api и 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. Запускает цикл событий,

Одна вещь, которая вас подойдет, доступ к атрибутам (объективные атрибуты c) не будет работать так же, как доступ к атрибутам python. т.е. в питона вы class_name.att для Objective C в Python вы должны назвать его как функцию, т.е. из моего примера ниже: 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 !, НЕ !;)

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 в свой файл AppleScript и назовите его «Time Machine», чтобы сделать иллюзию законченной. :-)

Смежные вопросы