최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday

티스토리 뷰

   AIR에서 다른 파일 실행하기


DID (디지털 정보 디스플레이 - 디지털 안내 데스크를 떠올리면 된다.) 기반의 Window Embedded Standard 7 에서 동작하는


각기 다른 두 개의 프로그램을 만들었다. 그런데 실제 서비스가 아닌, 프로젝트의 행사 소개에서 화면을 보여줄 요량으로


리모트 페이지가 필요한 상황이다.



이 리모트 페이지는 내가 만든 프로그램1, 2를 단순히 클릭하면 띄워주는 용도로 사용될 것이며


바로 이럴때 웹 기반 HTML의 A 태그를 사용하면 참으로 간단한데 예상했듯이 보안으로 인해 적용해 보면 각종 알럿과 에러가 뜬다.


확장자는 OOO.exe 로 되어있고 AIR 레퍼런스중 File 부분의 내용을 살펴보면 된다.




   AIR의 File 객체 작업


File 객체는 파일 시스템에 있는 파일 또는 디렉토리에 대한 포인터이다. 


주로 다음과 같은 작업에 File 클래스를 사용할 수 있다.

  • 사용자 디렉토리, 사용자의 문서 디렉토리, 응용 프로그램이 시작된 디렉토리 및 응용 프로그램 디렉토리와 같은 특수 디렉토리에 대한 경로 가져오기

  • 파일 및 디렉토리 복사

  • 파일 및 디렉토리 이동

  • 파일 및 디렉토리 삭제(또는 휴지통으로 이동)

  • 디렉토리에 포함된 파일 및 디렉토리 나열

  • 임시 파일 및 폴더 만들기

기본적으로 File 객체의 경로는 두개의 속성이 있는데 다음과 같다.

속성

설명

nativePath

파일에 대한 플랫폼별 경로를 지정합니다. 예를 들어 Windows의 경우 경로는 "c:\Sample directory\test.txt"일 수 있는 반면 Mac OS에서는 "/Sample directory/test.txt"일 수 있습니다. nativePath 속성은 디렉토리 분리 기호 문자로 Windows에서는 백슬래시(\) 문자를 사용하고 Mac OS 및 Linux에서는 슬래시(/) 문자를 사용합니다.

url

이 속성은 파일 URL 스킴을 사용하여 파일을 가리킬 수 있습니다. 예를 들어 Windows의 경우 경로는 "file:///c:/Sample%20directory/test.txt"일 수 있는 반면 Mac OS에서는 "file:///Sample%20directory/test.txt"일 수 있습니다. 런타임에는 file 외에도 다른 특수 URL 스킴이 포함되어 있으며 이에 대해서는 지원되는 AIR URL 스킴에서 설명합니다.



File 클래스를 통해 특정 파일 경로를 가리킬 수 있지만 그렇게 하면 응용 프로그램을 서로 다른 플랫폼에 걸쳐 사용하지 못할 수 있다.


예를 들어 C:\Documents and Settings\joe\와 같은 경로는 Windows 운영 체제에서만 사용할 수 있다. 이러한 경우를 피하기 위해 


아래와 같이 File.documentsDirectory 같은 File 클래스의 정적 속성을 사용하는 것이 좋다고 추천한다.


var prefsFile:File = File.applicationStorageDirectory; prefsFile = prefsFile.resolvePath("preferences.xml");



   File 객체로 디렉토리 가리키기


디렉토리를 가리키도록 하기위해 File 객체를 설정하는 여러가지 방법이 있다. 간략하게만 살펴보겠다.


var file:File = File.desktopDirectory.resolvePath("AIR Test"); // 바탕화면 디렉토리 가리키리


var file:File = File.documentsDirectory.resolvePath("AIR Test"); // 사용자 문서 디렉토리 가리키기


var file:File = File.userDirectory.resolvePath("AIR Test"); // 사용자 홈 디렉토리 가리키기 등등..많음


Windows의 경우 Documents and Settings 디렉토리에서:


C:\Documents and Settings\user name\Application Data\applicationID\Local Store\   는


C:\Documents and Settings\babbage\Application Data\com.example.TestApp\Local Store 이렇게 표현.


Linux의 경우:


/home/user name/.appdata/applicationID/Local Store/


/home/babbage/.appdata/com.example.TestApp/Local Store


Android의 경우:


/data/data/androidPackageID/applicationID/Local Store


/data/data/air.com.example.TestApp/com.example.TestApp/Local Store



   File 객체로 파일 가리키기


드디어 파일이다.


명시적으로 파일 경로를 가리키는 방법은 직관적이긴 하나 특정 플랫폼에만 사용할 수 있는 코드가 작성될 수 있다.


예를 들어서 C:/foo.txt와 같은 경로는 windows에서만 사용할 수 있고, 위에서 언급했듯이 File 객체의 정적속성인


File.applicationStorageDirectory 등..을 이용하면 플랫폼에 관계없이 작동하는 디렉토리를 찾을 수 있다. 


그런다음 resolvePath()메서드를 사용하여 상대 경로로 이동한다. 다음의 예는 url속성을 사용한 URL문자열 기반의 경로이다.


var urlStr:String = "file:///C:/AIR Test/test.txt";

var file:File = new File()

file.url = urlStr;


물론 우리가 흔히 URLRequst의 생성자 함수에 URL로 전달해서 스트링을 부여하듯 다음과 같이 쓸 수있다.


var urlStr:String = "file:///C:/AIR Test/test.txt";

var file:File = new File(urlStr);


위의 두 단계 중 가장 축약형으로 쓸 수도 있다.


var file:File = new File("C:/AIR Test/test.txt");


The url property always returns the URI-encoded version of the URL (for example, blank spaces are replaced with "%20):

공백이 있을 경우 %20으로 대체하여 표시.


file.url = "file:///c:/AIR Test"; 

trace(file.url); // file:///c:/AIR%20Test 



   기본 시스템 응용 프로그램으로 파일 열기


이제 마지막 단계이다. OS에서 AIR를 사용하여 파일을 열 수 있는데, API를 보면 DOC 파일을 열도록 등록된 응용 프로그램을 사용하여


DOC 파일을 열 수 있다. 라고 되어있다. 이 말은 DOC 파일에 대한 기본 응용 프로그램으로 이 파일을 연다는 뜻이다.


메서드는 File 객체의 openWithDefaultApplication() 를 사용한다. 참  길기도하다. DOC 파일의 경우 다음과 같이 사용한다는 것이다.


var file:File = File.deskopDirectory;

file = file.resolvePath("test.doc");

file.openWithDefaultApplication();


참고로 윈도우의 경우 확장자로 파일 유형을 결정하지만, Linux의 경우는 파일의 MIME 유형에 따라 파일의 기본 응용 프로그램이


결정된다.



   반전. AIR에서는 사용자가 특정 파일을 열 수 없습니다!


.....문서의 10/9 를 읽고 대략적인 사용방법과 주요 메서드를 파악한 후 10/10에 도달하여 실제 써있는 문구이다.


정확히 아래와 같이 적혀있다.


AIR에서는 사용자가 openWithDefaultApplication() 메서드를 사용하여 특정 파일을 열 수 없습니다.

Windows의 경우, AIR에서 사용자가 EXE 또는 BAT와 같은 특정 파일 유형을 열 수 없습니다.

Mac OS 및 Linux의 경우 AIR가 특정 응용 프로그램에서 실행되는 파일을 열 수 없습니다.

이러한 응용 프로그램에는 Mac OS의 경우 Terminal 및 AppletLauncher, Linux의 경우 csh, bash 또는 ruby가 포함됩니다. openWithDefaultApplication() 메서드를 사용하여 이러한 파일 중 하나를 열려고 하면 예외가 발생합니다.

열 수 없는 파일 유형의 전체 목록은 File.openWithDefaultApplication() 메서드의 언어 참조 항목을 참조하십시오.


그리고 저 글상자 바로 밑에 한줄로


Note: This limitation does not exist for an AIR application installed using a native installer (an extended desktop application).

참고: 이 제한은 기본 설치 프로그램으로 설치한 AIR 응용 프로그램(확장된 데스크톱 응용 프로그램)에는 적용되지 않습니다


도대체 AIR로 파일이 열리긴 열리다는 것인가.. 그리고 확장된 데스크톱 응용 프로그램은 또 무슨소리인가...


다음 이어지는 내용을 읽어보면 해결방법이 있다.



   파일 연결및 테스트


일반적인 텍스트파일이나 이미지 파일은 디버깅 혹은 AIR Package프로그램으로 파일 연결이 가능하다.


가령 C드라이브의 AIR Test 폴더안에 있는 text.txt 파일을 연결및 실행하면 다음과 같다.


package
{
	import flash.display.Sprite;
	import flash.filesystem.File;
	
	[SWF(framRate="24", width="400", height="300", backgroundColor="0x000000")]
	
	public class AIR_TEST extends Sprite
	{
		var urlStr:String = "file:///C:/AIR Test/text.txt";
		var file:File = new File();
		file.url = urlStr; 
		file.openWithDefaultApplication();
	}
}


결과 : 프로그램이 시작되자 마자 연결 파일이 실행 됨. 그러나 exe같은 예외파일은 IllegalOperationError 를 낸다.



이번에는 C드라이브의 AIR Test 폴더안에 있는 test.ext 파일이다.


package
{
	import flash.display.Sprite;
	import flash.filesystem.File;
	
	[SWF(framRate="24", width="400", height="300", backgroundColor="0x000000")]
	
	public class AIR_TEST extends Sprite
	{
		var urlStr:String = "file:///C:/AIR Test/text.exe";
		var file:File = new File();
		file.url = urlStr; 
		file.openWithDefaultApplication();
	}
}


API에서 자꾸 강조하는 AIR 응용프로그램-확장된 데스크톱 프로그램 (말도 어렵다) 으로 릴리즈 하면 만사OK다.


바로 저기에 체크해서 인스톨 파일 패키지가 ".air" 가 아닌 ".exe" 파일 (exe file for installation)


즉, Signed native installer 에 체크해서 릴리즈하면 모든 규약에서 벗어난다.



만약 Signed native installer에 체크하지 않아서 열 수 없는 문서의 항목은 다음과 같다. 맨땅에 헤딩 하는일이 없길 바라며...


일반 air 패키지(Signed AIR package)로는 얘네들을 열 수 없다.





   최종 구현 코드


본인이 구현한 코드는 다음과 같다. 단순히 몇줄안되는 코드만으로도 파일을 open할 수 있다.


/**********************************************
 * by serpiko (http://serpiko.tistory.com/)
 **********************************************/
package
{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	
	[SWF(framRate="24", width="400", height="300", backgroundColor="0x000000")]
	
	public class AIR_TEST extends Sprite
	{
		private var sp1:Sprite;
		private var sp2:Sprite;
		
		public function AIR_TEST()
		{
			display();
			addEvent();
		}
		
		private function display():void{
			sp1 = new Sprite();
			sp1.graphics.lineStyle(1, 0xFFFFFF, 1);
			sp1.graphics.beginFill(0xFF0066, 1);
			sp1.graphics.drawRect(20, 100, 150, 100);
			addChild(sp1);
			
			sp2 = new Sprite();
			sp2.graphics.lineStyle(1, 0xFFFFFF, 1);
			sp2.graphics.beginFill(0xFF3300, 1);
			sp2.graphics.drawRect(220, 100, 150, 100);
			addChild(sp2);
		}
		
		private function addEvent():void{
			sp1.buttonMode = true;
			sp2.buttonMode = true;
			sp1.addEventListener(MouseEvent.CLICK, typeA);
			sp2.addEventListener(MouseEvent.CLICK, typeB);
		}
		
		private function typeA(e:MouseEvent):void{
			var urlStr:String = "file:///C:/AIR Test/CHEONGJU_ARTCENTER/CHEONGJU_ARTCENTER.exe";
			var file:File = new File();
			file.url = urlStr; 
			file.openWithDefaultApplication();
		}
		
		private function typeB(e:MouseEvent):void{
			var urlStr:String = "file:///C:/AIR Test/CHEONGJU_ARTCENTER/CHEONGJU_ARTCENTER.exe";
			var file:File = new File();
			file.url = urlStr; 
			file.openWithDefaultApplication();
		}
	}
}


참고로 여기에 시스템이 유휴 모드로 전환되지 않도록 하는 처리만 하면 리모트로서의 페이지로 완성도를 높혀 나갈 것이다.

NativeApplication 패키지의 SystemIdelMode 속성에서 제어한다.

import flash.desktop.NativeApplication;
import flash.desktop.SystemIdleMode;


NativeApplication.nativeApplication.addEventListener (Event.ACTIVATE, notSleep);

//시스템이 유휴 모드로 전환되지 않도록 합니다.
function notSleep(e:Event):void
{
 NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE;
}


결과 창)




일부 설정파일 "Export As"에 대한 용어가 들어있어서 이 내용만 영어 원문 그대로 표현하는게 오차가 없었을 것이라고 판단된다.

영어 레퍼런스의 주소는 다음과 같다.


http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118666ade46-7fe4.html#WS2A7C0A31-A6A9-42d2-8772-79166A98A085







댓글