AIR의 기본 프로세스와 통신

Adobe AIR 2 이상

Adobe AIR 2에서는 명령줄을 통해 AIR 응용 프로그램이 실행되고 다른 기본 프로세스와 통신할 수 있습니다. 예를 들어 AIR 응용 프로그램에서 프로세스를 실행하고 표준 입력 및 출력 스트림을 통해 해당 프로세스와 통신할 수 있습니다.

기본 프로세스와 통신하려면 기본 설치 프로그램을 통해 설치되도록 AIR 응용 프로그램을 패키지화해야 합니다. 기본 설치 프로그램의 파일 유형은 설치되는 운영 체제에 따라 다릅니다.

  • Mac OS의 경우 DMG 파일

  • Windows의 경우 EXE 파일

  • Linux의 경우 RPM 또는 DEB 패키지

이러한 응용 프로그램을 확장 데스크톱 프로파일 응용 프로그램이라고 합니다. ADT를 사용하여 -target native 옵션( -package 명령 호출 시)을 지정하여 기본 설치 프로그램 파일을 만들 수 있습니다.

기본 프로세스 통신 개요

확장 데스크톱 프로파일의 AIR 응용 프로그램은 명령줄에서 호출된 것처럼 파일을 실행할 수 있으며 기본 프로세스의 표준 스트림과 통신할 수 있습니다. 표준 스트림에는 표준 입력 스트림(stdin), 출력 스트림(stdout), 표준 오류 스트림(stderr)이 포함됩니다.

참고: 확장 데스크톱 프로파일의 응용 프로그램은 File.openWithDefaultApplication() 메서드를 사용하여 파일 및 응용 프로그램을 실행할 수도 있습니다. 그러나 이 메서드를 사용하면 AIR 응용 프로그램에 표준 스트림에 대한 액세스 권한이 제공되지 않습니다. 자세한 내용은 기본 시스템 응용 프로그램으로 파일 열기 를 참조하십시오.

다음 코드 샘플에서는 응용 프로그램 디렉토리에서 test.exe 응용 프로그램을 실행하는 방법을 보여 줍니다. 응용 프로그램은 인수 "hello" 를 명령줄 인수로 전달하고 프로세스의 표준 출력 스트림에 이벤트 리스너를 추가합니다.

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

기본 프로세스 실행 및 닫기

기본 프로세스를 실행하려면 다음을 수행하도록 NativeProcessInfo 객체를 설정합니다.

  • 실행하려는 파일 가리키기

  • 시작 시 프로세스에 전달할 명령줄 인수 저장 (선택 사항)

  • 프로세스의 작업 디렉토리 설정(선택 사항)

기본 프로세스를 시작하려면 NativeProcessInfo 객체를 NativeProcess 객체의 start() 메서드에 대한 매개 변수로 전달합니다.

예를 들어 다음 코드에서는 응용 프로그램 디렉토리에서 test.exe 응용 프로그램을 실행하는 방법을 보여 줍니다. 응용 프로그램은 인수 "hello" 를 전달하고 사용자의 문서 디렉토리를 작업 디렉토리로 설정합니다.

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

프로세스를 종료하려면 NativeProcess 객체의 exit() 메서드를 호출합니다.

설치된 응용 프로그램에서 파일이 실행 가능하도록 하려면 해당 응용 프로그램을 패키지화할 때 파일 시스템에서 해당 파일을 실행할 수 있어야 합니다. Mac 및 Linux에서는 필요한 경우 chmod를 사용하여 실행 가능 플래그를 설정할 수 있습니다.

기본 프로세스와 통신

AIR 응용 프로그램이 기본 프로세스를 시작한 후에는 프로세스의 표준 입력, 표준 출력 및 표준 오류 스트림과 통신할 수 있습니다.

NativeProcess 객체의 다음 속성을 사용하여 스트림에서 데이터를 읽고 쓸 수 있습니다.

  • standardInput - 표준 입력 스트림 데이터에 대한 액세스를 포함합니다.

  • standardOutput - 표준 출력 스트림 데이터에 대한 액세스를 포함합니다.

  • standardError - 표준 오류 스트림 데이터에 대한 액세스를 포함합니다.

표준 입력 스트림에 쓰기

NativeProcess 객체의 standardInput 속성에 대한 쓰기 메서드를 사용하여 표준 입력 스트림에 데이터를 쓸 수 있습니다. AIR 응용 프로그램이 프로세스에 데이터를 쓰면 NativeProcess 객체가 standardInputProgress 이벤트를 전달합니다.

표준 입력 스트림에 쓰는 동안 오류가 발생하면 NativeProcess 객체가 ioErrorStandardInput 이벤트를 전달합니다.

NativeProcess 객체의 closeInput() 메서드를 호출하여 입력 스트림을 닫을 수 있습니다. 입력 스트림이 닫히면 NativeProcess 객체가 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(); 
}

표준 출력 스트림에서 읽기

이 속성의 읽기 메서드를 사용하여 표준 출력 스트림에서 데이터를 읽을 수 있습니다. AIR 응용 프로그램이 프로세스에서 출력 스트림 데이터를 가져오면 NativeProcess 객체가 standardOutputData 이벤트를 전달합니다.

표준 출력 스트림에 쓰는 동안 오류가 발생하면 NativeProcess 객체가 standardOutputError 이벤트를 전달합니다.

프로세스에서 출력 스트림을 닫으면 NativeProcess 객체가 standardOutputClose 이벤트를 전달합니다.

표준 입력 스트림에서 데이터를 읽을 때는 생성된 대로 데이터를 읽어야 합니다. 즉, standardOutputData 이벤트에 대한 이벤트 리스너를 추가한 후 standardOutputData 이벤트 리스너에서 NativeProcess 객체의 standardOutput 속성으로부터 데이터를 읽어야 합니다. 단순히 standardOutputClose 이벤트 또는 exit 이벤트에서 모든 데이터를 읽을 때까지 기다리면 안 됩니다. 기본 프로세스에서 데이터가 생성된 대로 데이터를 읽지 않을 경우 버퍼가 가득 차서 데이터가 손실될 수 있습니다. 버퍼가 차면 데이터를 더 쓰려고 시도할 때 기본 프로세스가 멈출 수 있습니다. 반면 standardOutputData 이벤트에 대한 이벤트 리스너를 등록하지 않을 경우 버퍼가 차지 않아 프로세스가 멈추지 않습니다. 이 경우 데이터에 액세스할 수 없습니다.

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

표준 오류 스트림에서 읽기

이 속성의 읽기 메서드를 사용하여 표준 오류 스트림에서 데이터를 읽을 수 있습니다. AIR 응용 프로그램이 프로세스에서 오류 스트림 데이터를 읽으면 NativeProcess 객체가 standardErrorData 이벤트를 전달합니다.

표준 오류 스트림에 쓰는 동안 오류가 발생하면 NativeProcess 객체가 standardErrorIoError 이벤트를 전달합니다.

프로세스에서 오류 스트림을 닫으면 NativeProcess 객체가 standardErrorClose 이벤트를 전달합니다.

표준 오류 스트림에서 데이터를 읽을 때는 생성된 대로 데이터를 읽어야 합니다. 즉, standardErrorData 이벤트에 대한 이벤트 리스너를 추가한 후 standardErrorData 이벤트 리스너에서 NativeProcess 객체의 standardError 속성으로부터 데이터를 읽어야 합니다. 단순히 standardErrorClose 이벤트 또는 exit 이벤트에서 모든 데이터를 읽을 때까지 기다리면 안 됩니다. 기본 프로세스에서 데이터가 생성된 대로 데이터를 읽지 않을 경우 버퍼가 가득 차서 데이터가 손실될 수 있습니다. 버퍼가 차면 데이터를 더 쓰려고 시도할 때 기본 프로세스가 멈출 수 있습니다. 반면 standardErrorData 이벤트에 대한 이벤트 리스너를 등록하지 않을 경우 버퍼가 차지 않아 프로세스가 멈추지 않습니다. 이 경우 데이터에 액세스할 수 없습니다.

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

기본 프로세스 통신에 대한 보안 고려 사항

기본 프로세스 API는 사용자 시스템의 모든 실행 파일을 실행할 수 있습니다. 명령을 생성하고 실행할 때는 각별한 주의가 필요합니다. 실행할 명령의 일부를 외부 소스에서 가져오는 경우 해당 명령이 실행하기에 안전한지 신중하게 유효성을 검사해야 합니다. 마찬가지로 AIR 응용 프로그램은 실행 프로세스로 전달되는 모든 데이터의 유효성을 검사해야 합니다.

그러나 입력의 유효성을 검사하는 것은 어려운 작업일 수 있습니다. 이와 같은 어려움을 없애려면 특정 API가 포함된 기본 응용 프로그램(예: Windows의 EXE 파일)을 작성하는 것이 가장 좋습니다. 이러한 API는 해당 응용 프로그램에서 정의한 명령만 처리해야 합니다. 예를 들어 응용 프로그램에서 표준 입력 스트림을 통해 제한된 명령 세트만 허용할 수 있습니다.

Windows에서 AIR를 사용하는 경우 .bat 파일을 직접 실행할 수 없습니다. 대신 명령 인터프리터 응용 프로그램(cmd.exe)을 사용하여 Windows .bat 파일을 실행합니다. .bat 파일을 호출하면 이 명령 응용 프로그램에서 명령에 전달된 인수를 추가로 실행해야 할 응용 프로그램으로 해석할 수 있습니다. 인수 문자열에 추가 문자를 악의적으로 삽입할 경우 cmd.exe가 유해하거나 안전하지 않은 응용 프로그램을 실행할 수 있습니다. 예를 들어 올바른 데이터 유효성 검사를 수행하지 않으면 AIR 응용 프로그램이 myBat.bat myArguments c:/evil.exe 를 호출할 수 있습니다. 명령 응용 프로그램에서 일괄 처리 파일을 실행할 뿐 아니라 evil.exe 응용 프로그램도 실행하게 됩니다.