Kommunikation mit nativen Prozessen in AIR

Adobe AIR 2 und höher

Ab Adobe AIR 2 können AIR-Anwendungen über die Befehlszeile ausgeführt werden und mit anderen nativen Prozessen kommunizieren. Beispielsweise kann eine AIR-Anwendung über die standardmäßigen Ein- und Ausgabestreams einen Prozess ausführen und mit ihm kommunizieren.

Zur Kommunikation mit nativen Prozessen muss eine AIR-Anwendung so verpackt werden, dass sie über ein natives Installationsprogramm installiert wird. Der Dateityp eines nativen Installationsprogramms richtet sich nach dem jeweiligen Betriebssystem:

  • DMG-Datei unter Mac OS.

  • EXE-Datei unter Windows.

  • RPM- oder DEB-Paket unter Linux.

Diese Anwendungen werden als erweiterte Desktop-Profilanwendungen bezeichnet. Sie erstellen eine native Installationsdatei, indem Sie die -target native -Option angeben, wenn Sie den -package -Befehl mit ADT aufrufen.

Überblick über die Kommunikation mit nativen Prozessen

Eine AIR-Anwendung in einem erweiterten Desktop-Profil kann eine Datei genauso ausführen wie beim Aufruf über die Befehlszeile. Sie kann mit den Standardstreams des nativen Prozesses kommunizieren. Zu den Standardstreams zählen der Standardeingabestream (stdin), der Ausgabestream (stdout) und der Standardfehlerstream (stderr).

Hinweis: Anwendungen im erweiterten Desktop-Profil können Dateien und Anwendungen auch über die File.openWithDefaultApplication() -Methode starten. Bei Verwendung dieser Methode hat die AIR-Anwendung jedoch keinen Zugriff auf die Standardstreams. Weitere Informationen finden Sie unter Öffnen von Dateien mit der Standardsystemanwendung .

Das folgende Codebeispiel zeigt, wie die Anwendung „test.exe“ im Anwendungsverzeichnis gestartet wird. Die Anwendung übergibt "hello" als Befehlszeilenargument und fügt dem Standardausgabestream des Prozesses einen Ereignis-Listener hinzu:

var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo(); 
var file:File = File.applicationDirectory.resolvePath("test.exe"); 
nativeProcessStartupInfo.executable = file; 
var processArgs:Vector.<String> = new Vector.<String>(); 
processArgs.push("hello"); 
nativeProcessStartupInfo.arguments = processArgs; 
process = new NativeProcess(); 
process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData); 
process.start(nativeProcessStartupInfo); 
public function onOutputData(event:ProgressEvent):void 
{ 
    var stdOut:ByteArray = process.standardOutput; 
    var data:String = stdOut.readUTFBytes(process.standardOutput.bytesAvailable); 
    trace("Got: ", data); 
}

Starten und Schließen eines nativen Prozesses

Zum Starten eines nativen Prozesses richten Sie ein NativeProcessInfo-Objekt ein, das folgende Schritte ausführt:

  • Verweisen auf die zu startende Datei

  • Speichern von Befehlszeilenargumenten, die nach dem Starten an den Prozess übergeben werden sollen (optional)

  • Festlegen des Arbeitsverzeichnisses für den Prozess (optional)

Zum Starten des nativen Prozesses muss das NativeProcessInfo-Objekt als Parameter der start() -Methode eines NativeProcess-Objekts übergeben werden.

Der folgende Code zeigt beispielsweise, wie die Anwendung „test.exe“ im Anwendungsverzeichnis gestartet wird. Die Anwendung übergibt das Argument "hello" und legt das Dokumentverzeichnis des Anwenders als Arbeitsverzeichnis fest:

var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo(); 
var file:File = File.applicationDirectory.resolvePath("test.exe"); 
nativeProcessStartupInfo.executable = file; 
var processArgs:Vector.<String> = new Vector.<String>(); 
processArgs[0] = "hello"; 
nativeProcessStartupInfo.arguments = processArgs; 
nativeProcessStartupInfo.workingDirectory = File.documentsDirectory; 
process = new NativeProcess(); 
process.start(nativeProcessStartupInfo); 

Zum Beenden des Prozesses rufen Sie die exit() -Methode des NativeProcess-Objekts auf.

Wenn eine Datei in der installierten Anwendung ausführbar sein soll, muss sie im Dateisystem ausführbar sein, wenn Sie die Anwendung verpacken. (Unter Mac und Linux können Sie das Flag für eine ausführbare Datei bei Bedarf mithilfe des chmod-Befehls festlegen.)

Kommunikation mit einem nativen Prozess

Nachdem eine AIR-Anwendung einen nativen Prozess gestartet hat, ist die Kommunikation mit dem Standardeingabestream, dem Standardausgabestream und dem Standardfehlerstream des Prozesses möglich.

Daten werden mit den folgenden Eigenschaften des NativeProcess-Objekts aus den Streams gelesen und in die Streams geschrieben:

  • standardInput – Ermöglicht den Zugriff auf die Daten des Standardeingabestreams.

  • standardOutput – Ermöglicht den Zugriff auf die Daten des Standardausgabestreams.

  • standardError – Ermöglicht den Zugriff auf die Daten des Standardfehlerstreams.

Schreiben in den Standardeingabestream

Zum Schreiben von Daten in den Standardeingabestream können Sie die write-Methoden der standardInput -Eigenschaft des NativeProcess-Objekts verwenden. Während die AIR-Anwendung Daten in den Prozess schreibt, setzt das NativeProcess-Objekt standardInputProgress -Ereignisse ab.

Wenn beim Schreiben in den Standardeingabestream ein Fehler auftritt, setzt das NativeProcess-Objekt ein ioErrorStandardInput -Ereignis ab.

Sie können den Eingabestream schließen, indem Sie die closeInput() -Methode des NativeProcess-Objekts aufrufen. Wenn der Eingabestream geschlossen wird, setzt das NativeProcess-Objekt ein standardInputClose -Ereignis ab.

var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo(); 
var file:File = File.applicationDirectory.resolvePath("test.exe"); 
nativeProcessStartupInfo.executable = file; 
process = new NativeProcess(); 
process.start(nativeProcessStartupInfo); 
process.standardInput.writeUTF("foo"); 
if(process.running) 
{ 
    process.closeInput(); 
}

Lesen aus dem Standardausgabestream

Zum Lesen von Daten aus dem Standardausgabestream verwenden Sie die read-Methoden dieser Eigenschaft. Während die AIR-Anwendung Ausgabestreamdaten vom Prozess erhält, setzt das NativeProcess-Objekt standardOutputData -Ereignisse ab.

Wenn beim Schreiben in den Standardausgabestream ein Fehler auftritt, setzt das NativeProcess-Objekt ein standardOutputError -Ereignis ab.

Wenn der Prozess den Ausgabestream schließt, setzt das NativeProcess-Objekt ein standardOutputClose -Ereignis ab.

Achten Sie beim Lesen von Daten aus dem Standardeingabestream darauf, die Daten direkt bei der Erstellung zu lesen. Fügen Sie also einen Ereignis-Listener für das standardOutputData -Ereignis hinzu. Im standardOutputData -Ereignis-Listener lesen Sie die Daten aus der standardOutput -Eigenschaft des NativeProcess-Objekts. Warten Sie nicht darauf, dass die Ereignisse standardOutputClose oder exit alle Daten lesen. Wenn Sie die Daten nicht direkt beim Erstellen durch den nativen Prozess lesen, kann der Puffer zu voll werden oder Daten können verloren gehen. Wenn der Puffer voll ist, kann dies dazu führen, dass der native Prozess beim Versuch, weitere Daten zu schreiben, angehalten wird. Wenn Sie jedoch keinen Ereignis-Listener für das standardOutputData -Ereignis registrieren, wird der Puffer nicht voll und der Prozess wird nicht angehalten. In diesem Fall haben Sie keinen Zugriff auf die Daten.

var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo(); 
var file:File = File.applicationDirectory.resolvePath("test.exe"); 
nativeProcessStartupInfo.executable = file; 
process = new NativeProcess(); 
process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, dataHandler); 
process.start(nativeProcessStartupInfo); 
var bytes:ByteArray = new ByteArray(); 
function dataHandler(event:ProgressEvent):void 
{ 
    bytes.writeBytes(process.standardOutput.readBytes(process.standardOutput.bytesAvailable); 
}

Lesen aus dem Standardfehlerstream

Zum Lesen von Daten aus dem Standardfehlerstream verwenden Sie die read-Methoden dieser Eigenschaft. Während die AIR-Anwendung Fehlerstreamdaten aus dem Prozess liest, setzt das NativeProcess-Objekt standardErrorData -Ereignisse ab.

Wenn beim Schreiben in den Standardfehlerstream ein Fehler auftritt, setzt das NativeProcess-Objekt ein standardErrorIoError -Ereignis ab.

Wenn der Prozess den Fehlerstream schließt, setzt das NativeProcess-Objekt ein standardErrorClose -Ereignis ab..

Achten Sie beim Lesen von Daten aus dem Standardfehlerstream darauf, die Daten direkt bei der Erstellung zu lesen. Fügen Sie also einen Ereignis-Listener für das standardErrorData -Ereignis hinzu. Im standardErrorData -Ereignis-Listener lesen Sie Daten aus der standardError -Eigenschaft des NativeProcess-Objekts. Warten Sie nicht darauf, dass die Ereignisse standardErrorClose oder exit alle Daten lesen. Wenn Sie die Daten nicht direkt beim Erstellen durch den nativen Prozess lesen, kann der Puffer zu voll werden oder Daten können verloren gehen. Wenn der Puffer voll ist, kann dies dazu führen, dass der native Prozess beim Versuch, weitere Daten zu schreiben, angehalten wird. Wenn Sie jedoch keinen Ereignis-Listener für das standardErrorData -Ereignis registrieren, wird der Puffer nicht voll und der Prozess wird nicht angehalten. In diesem Fall haben Sie keinen Zugriff auf die Daten.

var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo(); 
var file:File = File.applicationDirectory.resolvePath("test.exe"); 
nativeProcessStartupInfo.executable = file; 
process = new NativeProcess(); 
process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, errorDataHandler); 
process.start(nativeProcessStartupInfo); 
var errorBytes:ByteArray = new ByteArray(); 
function errorDataHandler(event:ProgressEvent):void 
{ 
    bytes.writeBytes(process.standardError.readBytes(process.standardError.bytesAvailable); 
}

Sicherheitsaspekte bei der Kommunikation mit nativen Prozessen

Die API für native Prozesse kann jede ausführbare Datei auf dem Benutzersystem ausführen. Seien Sie beim Konstruieren und Ausführen von Befehlen äußerst vorsichtig. Wenn ein Teil eines auszuführenden Befehls aus einer externen Quelle stammt, prüfen Sie sorgfältig, ob die Ausführung des Befehls sicher ist. Ebenso sollte die AIR-Anwendung alle Daten überprüfen, die an einen aktiven Prozess übergeben werden.

Die Validierung von Eingaben kann jedoch schwierig sein. Um diese Probleme zu vermeiden, schreiben Sie am besten eine native Anwendung (zum Beispiel eine EXE-Datei für Windows) mit spezifischen APIs. Diese APIs sollten nur die Befehle verarbeiten, die von der Anwendung definiert sind. Zum Beispiel könnte die Anwendung nur einen begrenzten Satz von Anweisungen über den Standardeingabestream akzeptieren.

AIR unter Windows lässt die direkte Ausführung von .bat-Dateien nicht zu. Die Befehlsinterpreter-Anwendung (cmd.exe) führt Windows-Dateien mit der Erweiterung „.bat“ aus. Wenn Sie eine .bat-Datei aufrufen, kann diese Befehlsanwendung Argumente, die an den Befehl übergeben werden, als zusätzlich zu startende Anwendungen interpretieren. Durch das böswillige Einfügen von zusätzlichen Zeichen in den Argumentstring könnte cmd.exe eine schädliche oder unsichere Anwendung ausführen. Ohne eine gute Datenvalidierung könnte Ihre Anwendung zum Beispiel myBat.bat myArguments c:/evil.exe aufrufen. Die Befehlsanwendung würde die Anwendung „evil.exe“ zusätzlich zu Ihrer Batchdatei ausführen.