py-appscript

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.