Mit Adobe AIR 2 kann man erstmals native Prozesse starten und mit diesen interagieren. Was bedeutet dies? Ganz einfach: AIR 2 kann die bisherige Security-Sandbox verlassen und andere Programme starten.

Dieser Artikel gibt eine Einführung in das Thema. Als einfaches Beispiel habe ich mir etwas einfallen lassen: Es wird gezeigt, wie man mithilfe von AIR 2 den Flex-Compiler (mxmlc) startet und ihn eine MXML-Datei kompilieren lässt :)

air-native-process-finished

Native Installer

Einen Nachteil hat das neue Feature: Nutzt man native Prozesse, kann die AIR-Anwendung nicht mehr mit der mittlerweile gewohnten Installationsmethode (z.B. Button/Badge auf der Website) beim Nutzer aufgespielt werden.

The NativeProcess class and its capabilities are only available to AIR applications installed with a native installer (desktop extended profile applications).

Das Programm ist also nicht mehr plattformunabhängig und benötigt einen betriebssystem-spezifischen Installer. Mithilfe des ADT-Tools aus dem AIR SDK werden letztendlich ein DMG-Installer (Mac) bzw. ein EXE-Installer (Windows) erzeugt und ausgeliefert.

NativeProcess.isSupported

Um zu überprüfen, ob NativeProcess unterstützt wird, gibt es die statische Eigenschaft NativeProcess.isSupported. Dies kann in Form eines Beispielprogramms z.B. so aussehen:
air-native-process-supported

Der Quellcode dazu lautet:

XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. :WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
  3.     :Label text="NativeProcess is supported: {NativeProcess.isSupported}"/>
  4. :WindowedApplication>

Wichtige Klassen: NativeProcess, NativeProcessStartupInfo

Das Kernstück ist die Klasse flash.desktop.NativeProcess. Mit ihr kann man ein Programm auf dem Host-System starten. Danach lassen sich Standard Input (stdin), Standard Output (stdout) und die Fehler (stderr) überwachen.

Die Klasse flash.desktop.NativeProcessStartupInfo sammelt die Informationen, die für das Starten des Programmes notwendig sind (z.B. Name und Speicherort des auszuführenden Datei, Argumente, etc.).

XML:
  1. var file:File = new File ("/Applications/FlexSDK/flex_sdk_4.0.0.12222/bin/mxmlc");
  2. var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
  3. nativeProcessStartupInfo.executable = file;
  4. process = new NativeProcess();
  5. process.start(nativeProcessStartupInfo);

Beim Dateinamen des auszuführenden Programms müsste man in der Praxis ggf. eine Fallunterscheidung der Betriebssysteme machen (z.B. Capabilities.os.toLowerCase().indexOf("win") größer -1 ?), um unterschiedliche Programmversion auszuführen.

Events

An einem Objekt vom Typ NativeProcess lassen sich auch einige neue Events registrieren. So gelangt man über ProgressEvent.STANDARD_OUTPUT_DATA an den Standard Output. Wenn das native Programm beendet wird, wird das Event flash.events.NativeProcessExitEvent abgefeuert.

XML:
  1. process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData); 
  2. process.addEventListener(NativeProcessExitEvent.EXIT, onStandardOutputClose);

Argumente

In vielen Fällen möchte man den Programm auch Parameter/Argumente mitgeben (z.B. ... -name Florian). Dazu erstellt man einfach ein Vector und fügt die einzelnen Argumente nacheinander hinzu.

XML:
  1. var args:Vector.> = new Vector.>;
  2. args.push("-name");
  3. args.push("Florian");
  4. nativeProcessStartupInfo.arguments = args;

Descriptor File

Das Descriptor File für die AIR 2 Beta hat sich etwas geändert. Wichtig ist es, den Namespace anzupassen (http://ns.adobe.com/air/application/2.0beta). Außerdem muss man zur Nutzung von nativen Prozessen die Zeile mit „supportedProfiles” neu hinzufügen.

Eine funktionierendes Descriptor-File sieht dann z.B. so aus:

XML:
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. xmlns="http://ns.adobe.com/air/application/2.0beta">
  3.     >de.florianplag.air2betademo>
  4.     >Air2Demo>
  5.     >v1>
  6.     >
  7.         >Main.swf>
  8.     >
  9.     >extendedDesktop>
  10. >

Quellcode

Der Quellcode des Eingangs genannten "Mini-Flex-Compiler"-Beispiels lautet am Stück:

XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. :WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="init()" layout="vertical">
  3.     :Script>
  4.        
  5.        
  6.             import flash.filesystem.File;
  7.             import flash.desktop.NativeProcess;
  8.             import flash.desktop.NativeProcessStartupInfo;
  9.        
  10.             private var process:NativeProcess;
  11.             private var processBuffer:ByteArray = new ByteArray();
  12.            
  13.             private function init():void {
  14.                 var file:File = new File ("/Applications/FlexSDK/flex_sdk_4.0.0.12222/bin/mxmlc");
  15.                
  16.                 var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
  17.                 nativeProcessStartupInfo.executable = file;
  18.                        
  19.                 var args:Vector. = new Vector.;
  20.                 args.push("/Users/flo/Documents/workspace/Test2/src/Dummy.mxml");
  21.                 nativeProcessStartupInfo.arguments = args;   
  22.                
  23.                 process = new NativeProcess();
  24.                 process.start(nativeProcessStartupInfo);
  25.                
  26.                 process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData); 
  27.                 process.addEventListener(NativeProcessExitEvent.EXIT, onStandardOutputClose); 
  28.  
  29.             }
  30.            
  31.             private function onOutputData(event:ProgressEvent):void {
  32.                 process.standardOutput.readBytes(processBuffer, processBuffer.length);
  33.             }
  34.            
  35.             private function onStandardOutputClose(e:Event):void {
  36.                 myTxt.text += new String(this.processBuffer);
  37.             }         
  38.            
  39.         ]]>
  40.     :Script>
  41.     :TextArea id="myTxt"  width="300" height="300"/>
  42. :WindowedApplication>

Link: NativeProcess (ActionScript Hilfe)
Link: Interacting with a native process