py-aem manual | 5. Targeting applications

#

## 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.