Communication avec les processus natifs dans AIR

Adobe AIR 2 et ultérieur

Depuis Adobe AIR 2, les applications AIR peuvent exécuter d’autres processus natifs et communiquer avec eux via la ligne de commande. Une application AIR est ainsi capable d’exécuter un processus et de communiquer avec lui via les flux d’entrée et de sortie standard.

Pour communiquer avec les processus natifs, mettez en package une application AIR à installer via un programme d’installation natif. Le type de fichier du programme d’installation natif varie selon le système d’exploitation pour lequel il est créé :

  • C’est un fichier DMG sous Mac OS.

  • C’est un fichier EXE sous Windows.

  • C’est un package RPM ou DEB sous Linux.

Ces applications portent le nom d’applications à profil de bureau étendu. Pour créer un fichier de programme d’installation natif, vous spécifiez l’option -target native lorsque vous appelez la commande -package à l’aide d’ADT.

Présentation des communications avec les processus natifs

Une application AIR figurant dans le profil de bureau étendu peut exécuter un fichier comme s’il était appelé par la ligne de commande. Elle peut communiquer avec les flux standard du processus natif. Les flux standard incluent le flux d’entrée standard (stdin), le flux de sortie (stdout) et le flux d’erreur standard (stderr).

Remarque : les applications dotées d’un profil de bureau étendu peuvent également lancer des fichiers et des applications par le biais de la méthode File.openWithDefaultApplication() . L’utilisation de cette méthode ne permet toutefois pas à l’application AIR d’accéder aux flux standard. Pour plus d’informations, voir Ouverture de fichiers dans l’application système définie par défaut

Le code suivant illustre le lancement d’une application test.exe dans le répertoire d’application. L’application transmet l’argument "hello" sous forme d’argument de ligne de commande et ajoute un écouteur d’événements au flux de sortie standard du processus :

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

Lancement et fermeture d’un processus natif

Pour lancer un processus natif, définissez un objet NativeProcessInfo comme suit :

  • Pointez vers le fichier à lancer.

  • Enregistrez les arguments de ligne de commande à transmettre au processus lors du lancement (facultatif).

  • Définissez le répertoire de travail du processus (facultatif).

Pour démarrer le processus natif, transmettez l’objet NativeProcessInfo en tant que paramètre de la méthode start() d’un objet NativeProcess.

Le code suivant illustre par exemple le lancement d’une application test.exe dans le répertoire d’application. L’application transmet l’argument "hello" et définit le répertoire documents de l’utilisateur en tant que répertoire de travail :

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

Pour mettre fin au processus, appelez la méthode exit() de l’objet NativeProcess.

Si vous souhaitez qu’un fichier puisse être exécuté dans l’application installée, assurez-vous qu’il peut être exécuté sur le système de fichiers lors de la mise en package de l’application. (Sous Mac et Linux, vous disposez de chmod pour définir l’indicateur executable, le cas échéant.)

Communications avec un processus natif

Lorsqu’une application AIR démarre un processus natif, elle peut communiquer avec les flux d’entrée, de sortie et d’erreur standard de ce dernier.

Vous lisez et écrivez les données dans les flux à l’aide des propriétés suivantes de l’objet NativeProcess :

  • standardInput : permet d’accéder aux données du flux d’entrée standard.

  • standardOutput : permet d’accéder aux données du flux de sortie standard.

  • standardError : permet d’accéder aux données du flux d’erreur standard.

Ecriture dans le flux d’entrée standard

Vous pouvez écrire des données dans le flux d’entrée standard à l’aide des méthodes d’écriture de la propriété standardInput de l’objet NativeProcess. Lorsque l’application AIR écrit des données dans le processus, l’objet NativeProcess distribue des événements standardInputProgress .

S’il se produit une erreur lors de l’écriture dans le flux d’entrée standard, l’objet NativeProcess distribue un événement ioErrorStandardInput .

Pour fermer le flux d’entrée, appelez la méthode closeInput() de l’objet NativeProcess. Lors de la fermeture du flux d’entrée, l’objet NativeProcess distribue un événement 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(); 
}

Lecture dans le flux de sortie standard

Vous pouvez lire les données du flux de sortie standard par le biais des méthodes de lecture de cette propriété. Au fur et à mesure que l’application AIR extrait du processus les données du flux de sortie, l’objet NativeProcess distribue des événements standardOutputData .

S’il se produit une erreur lors de l’écriture du flux de sortie standard, l’objet NativeProcess distribue un événement standardOutputError .

Lorsque le processus ferme le flux de sortie, l’objet NativeProcess distribue un événement standardOutputClose .

Veillez à lire les données issues du flux d’entrée standard au fur et à mesure de leur génération. En d’autres termes, associez un écouteur à l’événement standardOutputData . Dans l’écouteur d’événements standardOutputData , lisez les données issues de la propriété standardOutput de l’objet NativeProcess. N’attendez pas l’événement standardOutputClose ou exit pour lire l’ensemble des données. Si vous ne lisez pas les données au fur et à mesure que le processus natif les génère, la mémoire tampon risque d’être saturée ou les données de se perdre. Une mémoire tampon saturée risque d’entraîner le blocage du processus natif lorsqu’il essaie d’écrire d’autres données. Toutefois, si vous n’associez pas d’écouteur à l’événement standardOutputData , la mémoire tampon ne se remplit pas et le processus ne se bloque pas. Il vous sera dans ce cas impossible d’accéder aux données.

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

Lecture dans le flux d’erreur standard

Vous pouvez lire les données du flux d’erreur standard par le biais des méthodes de lecture de cette propriété. Au fur et à mesure que l’application AIR lit dans le processus les données du flux d’erreur, l’objet NativeProcess distribue des événements standardErrorData .

S’il se produit une erreur lors de l’écriture du flux d’erreur standard, l’objet NativeProcess distribue un événement standardErrorIoError .

Lorsque le processus ferme le flux d’erreur, l’objet NativeProcess distribue un événement standardErrorClose ..

Veillez à lire les données issues du flux d’erreur standard au fur et à mesure de leur génération. En d’autres termes, associez un écouteur à l’événement standardErrorData . Dans l’écouteur d’événements standardErrorData , lisez les données extraites de la propriété standardError de l’objet NativeProcess. N’attendez pas l’événement standardErrorClose ou exit pour lire l’ensemble des données. Si vous ne lisez pas les données au fur et à mesure que le processus natif les génère, la mémoire tampon risque d’être saturée ou les données de se perdre. Une mémoire tampon saturée risque d’entraîner le blocage du processus natif lorsqu’il essaie d’écrire d’autres données. Toutefois, si vous n’associez pas d’écouteur à l’événement standardErrorData , la mémoire tampon ne se remplit pas et le processus ne se bloque pas. Il vous sera dans ce cas impossible d’accéder aux données.

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

Considérations liées à la sécurité qui affectent les communications avec le processus natif

L’API de processus natif peut exécuter tout fichier exécutable sur le système de l’utilisateur. Soyez extrêmement attentif lors de la création et de l’exécution de commandes. Si toute partie d’une commande à exécuter est issue d’une source externe, vérifiez méticuleusement son intégrité avant de l’exécuter. L’application AIR doit de même valider toute donnée transmise à un processus en cours d’exécution.

Toutefois, la validation d’une entrée s’avère parfois complexe. Par parer à ce problème, il est recommandé de programmer une application native (un fichier EXE sous Windows, par exemple) qui contient des API déterminées. Ces API ne doivent traiter que les commandes définies par l’application. L’application peut ainsi n’accepter qu’un jeu réduit d’instructions via le flux d’entrée standard.

Sous Windows, AIR ne vous autorise pas à exécuter directement les fichiers .bat. L’interpréteur de commande (l’application cmd.exe) exécute les fichiers .bat Windows. Lorsque vous appelez un fichier .bat, cette application peut interpréter les arguments transmis à la commande en tant applications supplémentaires à lancer. L’insertion malveillante de caractères supplémentaires dans la chaîne d’arguments risque de mener cmd.exe à exécuter une application nuisible ou non sécurisée. Ainsi, sans validation correcte des données, l’application AIR risque d’appeler myBat.bat myArguments c:/evil.exe . Outre le fichier batch, l’interpréteur de commandes lancerait l’application evil.exe.