Comunicazione con processi nativi in AIR

Adobe AIR 2 e versioni successive

A partire da Adobe AIR 2, le applicazioni AIR possono eseguire e comunicare con processi nativi mediante la riga di comando. Ad esempio, un'applicazione AIR può eseguire e comunicare con un processo mediante i flussi di input e output standard.

Per comunicare con processi nativi, create un pacchetto di un'applicazione AIR da installare tramite un programma di installazione nativo. Il tipo di file del programma di installazione nativo è specifico del sistema operativo per il quale viene creato:

  • Un file DMG in Mac OS.

  • Un file EXE in Windows.

  • Un pacchetto RPM o DEB in Linux.

Queste applicazioni sono note come applicazioni profilo desktop esteso. Potete creare un file del programma di installazione nativo specificando l'opzione -target native quando chiamate il comando -package utilizzando ADT.

Panoramica sulle comunicazioni processo nativo

Un'applicazione AIR nel profilo desktop esteso può eseguire un file, come se fosse richiamato dalla riga di comando, inoltre può comunicare con i flussi standard del processo nativo. I flussi standard includono il flusso di input standard (stdin), il flusso di output (stdout) e il flusso di errore standard (stderr).

Nota: le applicazioni nel profilo desktop esteso possono anche avviare file e applicazioni utilizzando il metodo File.openWithDefaultApplication() . Tuttavia, l'utilizzo di questo metodo non consente all'applicazione AIR di accedere ai flussi standard. Per ulteriori informazioni, vedete Apertura di file con l'applicazione di sistema predefinita

Il codice di esempio seguente mostra come avviare un'applicazione test.exe nella directory dell'applicazione. L'applicazione passa l'argomento "hello" come argomento della riga di comando e aggiunge un listener di eventi al flusso di output standard del processo:

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); 
}

Avvio e chiusura di un processo nativo

Per avviare un processo nativo, configurate un oggetto NativeProcessInfo per effettuare le seguenti operazioni:

  • Puntare al file che desiderate avviare

  • Memorizzare argomenti della riga di comando da passare al processo quando viene avviato (opzionale)

  • Impostare la directory di lavoro del processo (facoltativo)

Per avviare il processo nativo, passate l'oggetto NativeProcessInfo come parametro del metodo start() di un oggetto NativeProcess.

Ad esempio, il codice seguente illustra come avviare un'applicazione test.exe nella directory dell'applicazione. L'applicazione passa l'argomento "hello" e imposta la directory dei documenti dell'utente come directory di lavoro:

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); 

Per terminare il processo, chiamate il metodo exit() dell'oggetto NativeProcess.

Se desiderate che il file sia eseguibile nell'applicazione installata, accertatevi che sia eseguibile nel file system quando create un pacchetto dell'applicazione. (In Mac e Linux, potete utilizzare chmod per impostare il flag dell'eseguibile, se necessario.)

Comunicazione con un processo nativo

Dopo che è stato avviato, un processo nativo può comunicare con i flussi di input, output ed errore standard del processo.

Potete leggere e scrivere dati nei flussi utilizzando le seguenti proprietà dell'oggetto NativeProcess:

  • standardInput : contiene l'accesso ai dati del flusso di input standard.

  • standardOutputut : contiene l'accesso ai dati del flusso di output standard.

  • standardError : contiene l'accesso ai dati del flusso di errore standard.

Scrittura nel flusso di input standard

Potete scrivere dati nel flusso di input standard utilizzando i metodi di scrittura della proprietà standardInput dell'oggetto NativeProcess. Poiché l'applicazione AIR scrive i dati nel processo, l'oggetto NativeProcess invia eventi standardInputProgress .

Se si verifica un errore durante la scrittura nel flusso di input standard, l'oggetto NativeProcess invia un evento ioErrorStandardError .

Potete chiudere il flusso di input chiamando il metodo closeInput() dell'oggetto NativeProcess. Quando il flusso di input viene chiuso, l'oggetto NativeProcess invia un evento standardInputClose .

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(); 
}

Lettura dal flusso di output standard

Potete leggere dati dal flusso di output standard utilizzando i metodi di questa proprietà. Poiché l'applicazione AIR ottiene i dati del flusso di output dal processo, l'oggetto NativeProcess invia eventi standardOutputData .

Se si verifica un errore durante la scrittura nel flusso di output standard, l'oggetto NativeProcess invia un evento standardOutputError .

Quando il flusso di output viene chiuso, l'oggetto NativeProcess invia un evento standardOutputClose .

Quando leggete dati dal flusso di input standard, accertatevi di leggerli man mano che vengono generati. In altre parole, aggiungete un listener di eventi per l'evento standardOutputData . Nel listener di eventi standardOutputData , leggete i dati dalla proprietà standardOutput dell'oggetto NativeProcess. Non attendete semplicemente l'evento standardOutputClose o l'evento exit per leggere tutti i dati. Se non leggete i dati man mano che vengono generati dal processo nativo, il buffer potrebbe riempirsi o i dati essere persi. Un buffer pieno può causare il blocco del processo nativo quando cercate di scrivere più dati. Tuttavia, se non registrate un listener di eventi per l'evento standardOutputData , il buffer non si riempie e il processo non si blocca. In questo caso, non avrete accesso ai dati.

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); 
}

Lettura dal flusso di errore standard

Potete leggere dati dal flusso di errore standard utilizzando i metodi di questa proprietà. Poiché l'applicazione AIR legge i dati del flusso di errore dal processo, l'oggetto NativeProcess invia eventi standardErrorData .

Se si verifica un errore durante la scrittura nel flusso di errore standard, l'oggetto NativeProcess invia un evento standardErrorIoError .

Quando il flusso di errore viene chiuso, l'oggetto NativeProcess invia un evento standardErrorClose .

Quando leggete dati dal flusso di errore standard, accertatevi di leggere i dati man mano che vengono generati. In altre parole, aggiungete un listener di eventi per l'evento standardErrorData . Nel listener di eventi standardErrorData , leggete i dati dalla proprietà standardError dell'oggetto NativeProcess. Non attendete semplicemente l'evento standardErrorClose o l'evento exit per leggere tutti i dati. Se non leggete i dati man mano che vengono generati dal processo nativo, il buffer potrebbe riempirsi o i dati essere persi. Un buffer pieno può causare il blocco del processo nativo quando cercate di scrivere più dati. Tuttavia, se non registrate un listener di eventi per l'evento standardErrorData , il buffer non si riempie e il processo non si blocca. In questo caso, non avrete accesso ai dati.

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); 
}

Considerazioni relative alla sicurezza per le comunicazioni processo nativo

L'API NativeProcess permette di eseguire qualunque file eseguibile sul sistema dell'utente. Usate la massima attenzione quando create ed eseguite i comandi. Se qualunque parte di un comando da eseguire ha un'origine esterna, verificate attentamente che l'esecuzione del comando non presenti rischi per la sicurezza. Analogamente, la vostra applicazione AIR dovrà convalidare eventuali dati passati a un processo in esecuzione.

Tuttavia, la convalida dell'input può risultare difficoltosa. Per evitare tali difficoltà, è meglio scrivere un'applicazione nativa (ad esempio un file EXE in Windows) che abbia API specifiche. Tali API devono elaborare solo i comandi definiti dall'applicazione. Ad esempio, l'applicazione potrebbe accettare solo una serie limitata di istruzioni tramite il flusso di input standard.

In Windows, AIR non consente l'esecuzione diretta dei file .bat. L'applicazione interprete dei comandi (cmd.exe) esegue file .bat di Windows. Quando chiamate un file .bat, questa applicazione provvede a interpretare gli argomenti passati al comando come applicazioni aggiuntive da avviare. Un'iniezione malevola di caratteri supplementari nella stringa di argomenti potrebbe causare l'esecuzione da parte di cmd.exe di un'applicazione dannosa o non sicura. Ad esempio, senza un'adeguata convalida dei dati, l'applicazione AIR potrebbe chiamare myBat.bat myArguments c:/evil.exe . L'interprete dei comandi avvierebbe l'applicazione evil.exe in aggiunta all'elaborazione del file batch.