5. Targeting applications
The Application class
The Application class represents an application to which Apple events will be sent. Its constructor allows applications to be identified in one of five ways: by full path, by eppc URL, by Unix process id, by custom AEAddressDesc, or the host application if no other value is given. Its main method, event, is used to construct the Apple events to send. Several utility methods are also provided.
Application -- the target application
Static methods:
processexistsforpath(path) -- Does a local process launched
from the specified application file exist?
path : string -- application's path, e.g. '/System/Applications/Calendar.app'
Result : boolean -- Note: if path is invalid, an aem.ae.MacOSError
is raised.
processexistsforpid(pid) -- Is there a local application process
with the given unix process id?
pid : integer
Result : boolean
processexistsforurl(url) -- Does an application process specified
by the given eppc:// URL exist?
url : string -- url for remote process
(e.g. 'eppc://user:pass@192.168.2.1/TextEdit')
Result : bool -- Returns false if process doesn't exist, or if
access isn't allowed.
processexistsfordesc(desc) -- Does an application process specified
by the given AEAddressDesc exist?
desc : AEAddressDesc -- AEAddressDesc for application
Result : bool -- Returns false if process doesn't exist, or if
access isn't allowed.
launch(path, newinstance=False, hide=False) -- launch an application in
background if not already running, and send it a 'ascrnoop' event
path : str -- path to application, e.g. '/System/Applications/TextEdit.app'
newinstance : bool -- launch a new application instance?
hide : bool -- hide after launch?
Methods:
__init__(self, path=None, pid=None, url=None, desc=None,
codecs=aem.Codecs(), newinstance=False, hide=False)
path : string | None -- full path to local application
(e.g. '/System/Applications/TextEdit.app')
pid : integer | None -- Unix process id for local process
(e.g. 95)
url : string | None -- url for remote process
(e.g. 'eppc://user:pass@192.168.2.1/TextEdit')
desc : AEAddressDesc | None -- AEAddressDesc for application
codecs : aemtypes.Codecs -- used to convert Python values
to AEDescs and back
newinstance : bool -- when specifying application by path,
launch a new application instance?
hide : bool -- when specifying application by path,
hide after launch?
event(...) -- construct an Apple event (see next chapter for details)
begintransaction(self, session=None) -- begin a new transaction;
all Events constructed after begintransaction() is called will
belong to the same transaction until aborttransaction() or
endtransaction() is called
session : anything -- optional value identifying the
specific session (where supported)
endtransaction(self) -- end the current transaction
aborttransaction(self) -- abort the current transaction
reconnect(self) -- Make sure this Application object has the current
process ID for the target application, relaunching the
target application if it's not currently running.
(Note: this only works for Application objects specified
by path, not by PID, URL or AEDesc.)
Creating Application objects
When creating a new Application object, at most only one of the following arguments should be given: path, pid, url or desc. If none are given, the current application (host process) is targetted.
When targeting a local application by path, the full path to the application (or application bundle) must be given, including a .app suffix if present. Note that AEM identifies local applications by process serial number for reliability. If the target application is not already running when a new Application instance is created, it will be started automatically so that a PSN can be acquired. If the application can't be launched for some reason (e.g. if it's in the Trash), an aem.CantLaunchApplicationError error will be raised.
If the url argument is used, it should contain an eppc URL string. AEM will pack this as an AEDesc of typeApplSignature. The target machine must have Remote Apple Events enabled in its Sharing preferences.
Clients can also supply their own AEAddressDesc if they prefer. This should be a aem.ae.AEDesc of one of the following types:
typeApplicationBundleID
typeApplicationURL
typeApplSignature
typeKernelProcessID
typeMachPort
typeProcessSerialNumber
See the Apple Event Manager documentation for more information on these addressing modes.
The optional codecs argument can be used to specify the Codecs object to use when packing and unpacking Apple events created by this Application object. If no value is given, AEM's standard Codecs object is used. (Clients can also specify Codecs objects for individual events via the event method.)
The optional newinstance argument can be used to launch a new instance of the application, even if another instance is already running. (Caution: OS X applications are usually designed to operate as single instances and may not work correctly/at all if run as multiple instances.)
Launching applications
Application.launch is a static method attached to the Application class for convenience. It allows a non-running application to be launched without sending it the 'run' event (aevtoapp) normally sent to applications - a 'no-op' event (ascrnoop) is sent instead. It should be called before creating an Application object for the target application, otherwise the application will be launched as normal.
Transactions
The begintransaction and endtransaction methods are used to begin and end transaction sessions for applications that support this. All events created while a transaction session is active will be identified as part of that transaction.
Note that during a transaction, sending the application an event not created during that transaction will cause an error. Similarly, sending the application an event created during a transaction after that transaction has ended will cause an error.
The endtransaction method must be called to close both successful and failed transactions on completion. If a transaction session is accidentally left open, AEM will attempt to close it when the Application object's __del__ method is called, although this cannot be guaranteed to succeed.
Reconnecting to local applications
Because local applications are identified by process serial number, an existing Application object created using the path argument will no longer hold a valid AEAddressDesc if the target application quits. Sending events to an invalid address will cause an EventError -600 ("application isn't running") or -609 ("connection is invalid") to be raised.
The isrunning static method can be used to check if a local application is running or not, given its full path.
Calling the reconnect method will create a new AEAddressDesc for an existing Application object. If the application is not running at the time, it will be started automatically.
Note that only Event instances created after reconnect is called will receive the new AEAddressDesc. Any Event instances created before reconnect is called will still contain the old AEAddressDesc. Also note that the reconnect method will not work for Application objects created using either the url or desc arguments.
