Kommunicera med interna processer i AIR

Adobe AIR 2 och senare

Adobe AIR 2 och senare AIR-program kan köra och kommunicera med andra interna processer via kommandoraden. Ett AIR-program kan till exempel köra en process och samtidigt kommunicera med den via standardströmmarna för indata och utdata.

Om du vill kommunicera med interna processer paketerar du AIR-programmet så att det installeras med ett internt installationsprogram. Det interna installationsprogrammets filtyp är specifik för det operativsystem som det har skapats för:

  • I Mac OS är det en DMG-fil.

  • I Windows är det en EXE-fil.

  • I Linux är det ett RPM- eller DEB-paket.

De här programmen kallas för utökade skrivbordsprofiler. Du skapar en intern installationsfil genom att ange alternativet -target native när du anropar kommandot -package med hjälp av ADT.

Översikt över kommunikation med interna processer

Ett AIR-program i den utökade skrivbordsprofilen kan köra en fil på samma sätt som om den anropades av kommandoraden. Det kan kommunicera med standardströmmarna i den interna processen. Standardströmmar omfattar strömmar av standardindata (stdin), standardutdata (stdout) och standardfel (stderr).

Obs! Program i den utökade skrivbordsprofilen kan också starta filer och program med hjälp av metoden File.openWithDefaultApplication(). Men när den här metoden används får inte AIR-programmet åtkomst till standardströmmarna. Mer information finns i Öppna filer med standardsystemprogrammet

Följande kodexempel visar hur programmet test.exe startas i programkatalogen. Programmet skickar argumentet "hello" som ett kommandoradsargument och lägger till en händelseavlyssnare i processens standardutdataström:

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

Starta och avsluta en intern process

Om du vill starta en intern process anger du att objektet NativeProcessInfo ska göra följande:

  • Peka på den fil som du vill starta

  • Spara kommandoradsargument som ska skickas till processen när den startas (valfritt)

  • Ange processens arbetskatalog (valfritt)

Om du vill starta den interna processen skickar du objektet NativeProcessInfo som parametern för metoden start() för ett NativeProcess-objekt.

Följande kodexempel visar till exempel hur programmet test.exe startas i programkatalogen. Programmet skickar argumentet "hello" och anger användarens dokumentkatalog som arbetskatalog:

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

Om du vill avsluta processen anropar du NativeProcess-objektets exit()-metod

Om du vill att en fil ska kunna köras i det installerade programmet bör du kontrollera att den är körbar på filsystemet när du packar programmet. (På Mac och Linux kan du använda chmod för att ange den körbara flaggan, om detta behövs.)

Kommunicera med en intern process

När ett AIR-program har startat en intern process kan det kommunicera med processens strömmar av standardindata, standardutdata och standardfel.

Du skriver data till och läser data från strömmarna med hjälp av följande egenskaper i objektet NativeProcess:

  • standardInput – Innehåller åtkomst till data för standardindataströmmen.

  • standardOutput – Innehåller åtkomst till data för standardutdataströmmen.

  • standardError – Innehåller åtkomst till data för standardfelströmmen.

Skriva till standardindataströmmen

Du kan skriva data till standardindataströmmen med hjälp av skrivmetoder för egenskapen standardInput för objektet NativeProcess. När AIR-programmet skriver data till processen skickar objektet NativeProcess standardInputProgress-händelser.

Om ett fel inträffar när data skrivs till standardindataströmmen skickar objektet NativeProcess en ioErrorStandardInput-händelse.

Du kan stänga indataströmmen genom att anropa metoden closeInput() i objektet NativeProcess. När indataströmmen stängs skickar objektet NativeProcess en standardInputClose-händelse.

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

Läsa från standardutdataströmmen

Du kan läsa data från standardutdataströmmen med hjälp av den här egenskapens läsmetoder. När AIR-programmet tar emot data från processens utdataström skickar objektet NativeProcess standardOutputData-händelser.

Om ett fel inträffar när data skrivs till standardutdataströmmen skickar objektet NativeProcess en standardOutputError-händelse.

När processen avslutar utdataströmmen skickar objektet NativeProcess en standardOutputClose-händelse.

Se till att data läses samtidigt som de genereras när de läses från standardindataströmmen. Lägg med andra ord till en händelseavlyssnare för händelsen standardOutputData. Läs data i händelseavlyssnaren standardOutputData från egenskapen standardOutput för objektet NativeProcess. Vänta inte bara på att händelsen standardOutputClose eller exit ska läsa alla data. Om du inte läser data samtidigt som de genereras av den interna processen kan bufferten bli full och data kan förloras. En full buffert kan göra så att den interna processen hänger sig när mer data ska skrivas. Men om du inte registrerar en händelseavlyssnare för händelsen standardOutputData kommer bufferten inte att bli full och processen kommer inte att hänga sig. I det här fallet har du ingen åtkomst till dessa data.

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

Läsa från standardfelströmmen

Du kan läsa data från standardfelströmmen med hjälp av den här egenskapens läsmetoder. När AIR-programmet läser felströmsdata från processen skickar objektet NativeProcess standardErrorData-händelser.

Om ett fel inträffar när data skrivs till standardfelströmmen skickar objektet NativeProcess en standardErrorIoError-händelse.

När processen stänger felströmmen skickar objektet NativeProcess en standardErrorClose-händelse..

Se till att data läses samtidigt som de genereras när de läses från standardfelströmmen. Lägg med andra ord till en händelseavlyssnare för händelsen standardErrorData. Läs data i händelseavlyssnaren standardErrorData från egenskapen standardError för objektet NativeProcess. Vänta inte bara på att händelsen standardErrorClose eller exit ska läsa alla data. Om du inte läser data samtidigt som de genereras av den interna processen kan bufferten bli full och data kan förloras. En full buffert kan göra så att den interna processen hänger sig när mer data ska skrivas. Men om du inte registrerar en händelseavlyssnare för händelsen standardErrorData kommer bufferten inte att bli full och processen kommer inte att hänga sig. I det här fallet har du ingen åtkomst till dessa data.

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

Säkerhetsaspekter för kommunikation med interna processer

Den interna processen API kan köra alla körbara filer på användarens system. Du bör vara mycket försiktig när du konstruerar och kör kommandon. Om någon del av ett kommando som ska köras kommer från en extern källa kontrollerar du noga att det kommandot är säkert att köra. På samma sätt bör AIR-programmet validera alla data som skickas till en process som körs.

Det kan dock vara svårt att verifiera indata. För att slippa den här typen av problem är det bäst att skriva ett inbyggt program (t.ex. en EXE-fil i Windows) med specifika API:er. Dessa API:er bör endast bearbeta de kommandon som definieras av programmet. Exempelvis kanske programmet endast accepterar en begränsad uppsättning instruktioner via standardindataströmmen.

Med AIR på Windows kan du inte köra .bat-filer direkt. Kommandotolken (cmd.exe) kör .bat-filer i Windows. När du anropar en .bat-fil kan den här kommandotolken tolka de argument som skickas till kommandot som fler program som ska startas. Skadliga extratecken i argumentsträngen kan medföra att cmd.exe kör ett skadligt eller osäkert program. Utan korrekt dataverifiering kan ditt AIR-program till exempel anropa myBat.bat myArguments c:/evil.exe. Kommandotolken skulle då starta programmet evil.exe utöver din .bat-fil.