10 October 2011
You should be familiar with Flex and with compiling a basic native C-based application.
Additional requirements
Advanced
Adobe AIR applications can be packaged and delivered via a native installer application, such as an EXE installer file on Windows or a DMG file on Mac OS. Such applications have the ability to launch and communicate with native processes, using the NativeProcess class. This example application shows how to package an AIR application in a native installer. The AIR application launches a native application, which is installed with the AIR application. The Windows version of the AIR application includes an EXE file and the Mac OS version includes a native Mac OS application. In each case, the AIR application communicates with the native application using the standard input (STDIN) and standard output (STDOUT) streams.
The AIR application launches and communicates with the native application by using the ActionScript NativeProcess class. Native process launching and communication are available for AIR applications that use the extended desktop profile. These are applications that are packaged into native application installer applications (rather than via a cross-platform AIR file).
The NativeProcessTest.mxml file includes all the MXML and ActionScript source code for the Flex application. Upon application initialization, the init() method checks whether the AIR application supports the native process API:
if(NativeProcess.isSupported)
{
launchEchoTest();
}
else
{
textReceived.text = "NativeProcess not supported.";
}
If the application supports the native process API, then the launchEchoTest() method sets up the native process.
The launchEchoTest() method points to the appropriate version of the executable file (for Mac or Windows):
var file:File = File.applicationDirectory;
file = file.resolvePath("NativeApps");
if (Capabilities.os.toLowerCase().indexOf("win") > -1)
{
file = file.resolvePath("Windows/bin/echoTestWin.exe");
}
else if (Capabilities.os.toLowerCase().indexOf("mac") > -1)
{
file = file.resolvePath("Mac/bin/echoTestMac");
}
The launchEchoTest() method then passes that file reference as the executable property of a NativeFileStartupInfo object. And the method creates a new NativeProcess object:
var nativeProcessStartupInfo:NativeProcessStartupInfo = new
NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
process = new NativeProcess();
The launchEchoTest() method then sets up an event listener for the STDOUT stream of the native process:
process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
The launchEchoTest() method then sets up an event listener for the standardInputProgress event of the native process. The NativeProcess object dispatches this event when the data written to the STDIN stream is flushed:
process.addEventListener(ProgressEvent.STANDARD_INPUT_PROGRESS, inputProgressListener);
The launchEchoTest() method then starts the native process:
process.start(nativeProcessStartupInfo);
The MXML file includes basic user interface controls. It lets the user define text to send to the STDIN stream of the native application. And it includes a text area for displaying content from the application’s STDOUT stream:
<mx:HBox width="100%">
<mx:Label text="Send text:"/>
<mx:TextInput id="textToSend" width="100%"/>
<mx:Button label="Submit" click="writeData()"/>
</mx:HBox>
<mx:TextArea id="testReceived" width="100%" height="100%" />
When the user clicks the Submit button, the writeData() method sends text to the STDIN stream of the native application. It sends the string from the textToSend control, using the writeUTF() method of the standardInput property of the NativeProcess object, and closes the STDIN stream:
process.standardInput.writeUTF(textToSend.text + "\n");
process.closeInput();
When the STDIN stream closes, it received data on the stream. The native process then echoes the text back to the AIR application, via its STDOUT stream. The application then closes.
The AIR application's onOutputData() method is the event handler for the standardOutputData event of the NativeProcess object. It relays the STDOUT text to the user interface:
textReceived.text = process.standardOutput.readUTFBytes(process.standardOutput.bytesAvailable);
var date:Date = new Date();
dateField.text = date.toString();
The onOutputData() method then restarts the native process by calling the launchEchoTest() method:
launchEchoTest();
The application descriptor file uses the AIR 3 namespace.
The application descriptor file also includes the following definition:
<supportedProfiles>extendedDesktop</supportedProfiles>
This line of code ensures that the application will not run if packaged inadvertently as an AIR file. It can only be packaged into a native installer application. This puts the application in the extended desktop profile, which grants it the ability to call the native process API.
The source files include source C code for the native versions of application. The NativeApps/Mac/src/echoTestMac.c file is the source C code for the Mac version. The NativeApps/Windows/src/echoTestMac.c file is the source C code for the Windows version.
Both the Mac and Windows version of the application simply listen on the STDIN stream of the application and echo lines sent back to the STDOUT stream.
The Mac code includes the following lines:
#define BUFFER_SIZE 8192
int main(int argc, char** argv)
{
char buf[BUFFER_SIZE];
int cnt;
while ( !feof(stdin)
)
{
cnt = read(STDIN_FILENO, buf, sizeof buf);
if (-1 == cnt)
{
perror("read");
exit(1);
}
if (0 == cnt)
{
// eof reached...
exit(0);
}
write(STDOUT_FILENO, buf, cnt );
}
return 0;
}
The Windows code includes the following lines:
#define BUFFER_SIZE 8192
extern int _setmode( int, int );
extern int _fileno( FILE* );
void terminalHandler( int sig )
{
fclose( stdout );
exit(1);
}
int main(int argc, char** argv)
{
char buf[BUFFER_SIZE];
int cnt;
int bytesRead = 0;
_setmode( _fileno( stdin ), _O_BINARY );
_setmode( _fileno( stdout ), _O_BINARY );
signal( SIGABRT, terminalHandler );
signal( SIGTERM, terminalHandler );
signal( SIGINT, terminalHandler );
// close the pipe to exit the app
while ( !feof( stdin ) )
{
cnt = fread( buf, sizeof( char ), BUFFER_SIZE, stdin);
if ( ferror( stdin ))
{
perror("read failed");
exit(1);
}
fwrite( buf, sizeof( char ), cnt, stdout );
}
return 0;
}
Compile the C code into a native application for the operating systems your application will target. The source files for this sample include compiled versions for Windows and Mac OS.
When you test the application in ADL, the application has access to the native process API. When you package the application in a native installer version, it also has access to the native process API.
The application descriptor file also includes the following definition:
<supportedProfiles>extendedDesktop</supportedProfiles>
This line of code enforces the application to be packaged in a native installer application (rather than as an AIR file). When debugging an application that is limited to the extended desktop profile, ADL knows to grant it access to the native process API.
If your application descriptor file does not limit the application to the extended desktop profile, you can still debug with native profile functionality. To do this, invoke ADL from the command line and include the –profile extendedDesktop argument.
To package the application, invoke the ADT application using syntax to package a native installer application version.
You must run ADT on the same operating system as the target installer application. To generate a DMG file, run ADT on Mac OS. To generate an EXE installer file, run ADT on Windows.
For example, the following command packages a DMG file on Mac OS:
adt -package -storetype pkcs12 -keystore myCert.p12 -target
native NativeProcessTest.dmg NativeProcessTest-app.xml NativeProcessTest.swf
NativeApps/Mac/bin/echoTestMac icons
Before running this command, open the Terminal application and navigate to the output directory for your Flex project. Adjust the following:
For example, the following command packages an EXE installer file on Windows:
adt -package -storetype pkcs12 -keystore myCert.p12 -target
native NativeProcessTest.exe NativeProcessTest-app.xml NativeProcessTest.swf
NativeApps/Windows/bin/echoTestWindows icons
Before running this command, open a command line session and navigate to the output directory for your Flex project. Adjust the following:
For more information on using ADT and on using signing certificates, refer to "Packaging an AIR application in a native installer" in Building Adobe AIR applications.
For more information, refer to the following documentation: