How to store and use a native executable in a SWC with AIR? - actionscript-3

I am developing an AIR application. This application needs some hardware accesses that are not possible with AIR. I decided to use the NativeApplication class in AIR, which launches a C# executable. The AIR application and the "native" application then communicate with the standard output and standard input streams.
A bit like that:
private var np:NativeProcess = new NativeProcess();
private var npi:NativeProcessStartupInfo = new NativeProcessStartupInfo();
private var args:Vector.<String> = new Vector.<String>();
private function creationCompleteHandler(event:FlexEvent):void {
args.push("myCommand");
args.push("myParameter");
npi.arguments = args;
npi.executable = File.applicationDirectory.resolvePath("MyNativeExe.exe");
np.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onData);
np.start(npi);
}
private function onData(e:ProgressEvent):void {
while(np.standardOutput.bytesAvailable != 0) {
trace(String.fromCharCode(np.standardOutput.readByte()));
}
}
I put MyNativeExe.exe file in the application directory, set the "extendedDesktop" value in the *-app.xml supportedProfiles, and it works fine.
Now, I would like to create a kind of AS3 SWC library that embeds MyNativeExe.exe and which provide an AS3 class to manage the interaction with MyNativeExe.exe. Therefore I could easily reuse this work in other AIR projects by simply addind the SWC file as a library. I may have to manually add the "extendedDesktop" value to the new AIR projects, but it is not a problem.
And I am stuck. I can embed an EXE file in a SWC file, by manually selecting the resources to embed with Flash Builder but...
it will not be automatically embeded in the final SWF file as only the needed parts of the SWC file are merged with the SWF
even if it is (enforcing the merge with an [Embed] tag, ...), how can I access and execute the embedded EXE file? NativeProcessInfo.executable needs a File object, and not a byte stream.
The only idea I have would be to embed the EXE file with [Embed], load it as a byte array, create a new file with the byte array as data, and then execute the file. I don't know if it works, but I do not like the idea, as it implies having the EXE kind of duplicated.
Does someone have an idea?
Thank you!

You should look into the Air Native Extensions. Simply put, one of the a new features in Air 3.0 was the ability to compile and link to custom language extensions directly from air. I haven't found an example of using C# directly, but there is a link on that page to doing with managed C++.

Related

adding a fla file from ported flash project to haxe (openfl)

What I want is to convert a flash project to an openfl project (which is written in haxe) in order to use its cross platform feature. I used as3hx to convert actionscript classes of a flash project to haxe. Then I fix compile errors by hand, and fix a run time error too. When I compile the project, I see a blank black window, which means that graphics are not loaded. I convert the code and code is working fine, but I don't know what should I do with graphics. There is a fla file in flash project, which I don't know how to convert it to openfl.
Adobe Flash CC, which is the program used to write flash project, does the linkage of a symbol to a actionscript class, and I don't know how to do this in openfl.
In openfl, as far as I know, giving graphics to a class is done like this :
import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.display.Sprite;
import openfl.Assets;
class Main extends Sprite {
public function new () {
super ();
var bd:BitmapData = Assets.getBitmapData("img/openfl.png");
var b:Bitmap = new Bitmap(bd);
addChild(b);
}
}
Where the openfl.png is a graphical file in a special folder named img, which declared to be an assets path.
I use HaxeDevelop IDE.
Thanks for any help
You can't use FLA files inside OpenFL, there's only support for SWF files exported by Flash from those FLA files:
http://www.openfl.org/learn/tutorials/using-swf-assets/
OpenFL's "native" SWF playback functionality is limited but for simple graphics and animations it's usable as long as you figure out what features are actually being supported and limit yourself to those.

Access asset / resource file in an ActionScript Library project

I'm using an ActionScript Library project to share code and assets / resources between a Mobile and a Desktop ActionScript projects.
The library project has been added to the two other projects via the 'Add Project' option on the 'Library Path' tab, with the linkage type 'Merged into Code', and all the classes within it can be accessed by the other projects, and work properly.
However it contains a SQLite database file, which I want to copy out to the File.applicationStorageDirectory on the target system on the first load of the app, and I'm not sure how to get a reference to the file within the library project to copy it out.
The location of the db file is: LibraryProj - src/database/dbFile.db and I thought using File.applicationDirectory and then a path 'into' the swf would give me access to it, but none of the following tests say the file exists.
var test:File;
test = File.applicationDirectory.resolvePath("app:/src/database/dbFileDb.db");
trace("test.exists==" + test.exists);
test = File.applicationDirectory.resolvePath("src/database/dbFileDb.db");
trace("test.exists==" + test.exists);
test = File.applicationDirectory.resolvePath("database/dbFileDb.db");
trace("test.exists==" + test.exists);
test = File.applicationDirectory.resolvePath("dbFileDb.db");
trace("test.exists==" + test.exists);
Is this the correct method to copy resource / asset files out of a swf containing merged libraries and onto the app's storage directory? Is it even possible to share resources / assets from Library projects in this way?
Any advice would be very much appreciated.
After doing some more research about using the [Embed] tag in AS3, I've now worked out that this is what I should have been using to make the file available to consuming projects (I'd previously only used it for images, and didn't think of it for other file types too).
[Embed('igniteDb.db', mimeType="application/octet-stream")]
public static const myReferenceDbFile:Class;
To copy the file to the File.applicationStorageDirectory i'm using the following code. It converts the embedded file to a byte array, and then writes this out via a FileStream class to the destination file.
//write the embedded database file data into app user files directory
var bundleDbBytes:ByteArray;
bundleDbBytes = new myReferenceDbFile();//gets a reference to the embedded db file
var outputDbFile:File = File.applicationStorageDirectory.resolvePath(DB_FILE_NAME);
var fileStream:FileStream = new FileStream();
fileStream.open(outputDbFile, FileMode.UPDATE);
fileStream.writeBytes(bundleDbBytes);
fileStream.close();
And hey presto, the database is ready to use.

Flash builder, AS3 accessing embed files (compiling issue)

I have a problem when compiling embed files using Flash Builder,
If I have my class called "Testing" with this embed file:
[Embed(source = "myfile.xml", mimeType = "application/octet-stream")]
public static var MyFile:Class;
I can access the file by these 2 ways:
new Testing.MyFile();
or
var file:Class = getDefinitionByName("packagename.Testing_MyFile") as Class;
new file();
The first one works fine, but the other one doesn't find the class using getDefinitionByName.
I found that the swf doesn't create the object with the name packagename.Testing_MyFile.
Im moving code from FlashDevelop to Flash builder and the first one create those files, do you know if Flash Builder needs a special flag or something to create those file?
Thanks

How do I load local file as JSON source? AIR & Flash Builder 4.5

In a very simple first AIR application (I'm using Flash Builder 4.5), I am trying to accomplish the following on my MacBook:
Read a local file (JSON format) into the AIR app.
Parse through the file.
Display some selected contents in a grid.
That's it.
I've found an example that does some simple JSON parsing in Flex, but the problem is that it loads the JSON source from a remote web site.
So do I need to load any file-specific libraries to make this work in AIR? Or can I simply refer to the file by using the Mac file-path? I just want the local file to be the JSON source. The parsing is already taken care of.
You can use FileStream like:
var myFile:File = File.documentsDirectory.resolvePath("AIR Test/test.txt");
var myFileStream:FileStream = new FileStream();
myFileStream.open(myFile, FileMode.READ);
var yourJSONdata:String = myFileStream.readUTFBytes(myFileStream.bytesAvailable);
myFileStream.close();
Initializing a FileStream object, and opening and closing files

How to effectively load SWF libraries?

I am making an AS3 project in FB4. In our workflow, we have artists compile art into SWC files which the I then link as 'Referenced Libraries' in FB4.
Then I set the "Link Type" of the SWC files to "external" instead of merged into code. This should create SWFs corresponding to the SWC files in the output folder, right?
This doesn't seem to be the case. I am only seeing one SWF file: the main_app's.
I was trying to make it so that I can use a library manager to load the files dynamically.
I tried extracting the swfs manually, but it seems the main_app still compiles all the swcs to itself. I made sure the Link Type was set to external. The file size for the main_app between "external" and "merged to code" seem to be the same.
I've made a simple project in Flash Builder 4 and the only way I got the SWC->SWF happening is by creating a Flex Project instead of an ActionScript Project and selecting "Runtime shared library (RSL)" instead of "External". This is because the Flex framework have some classes that work out the loading of those libraries for you. It also automate the conversion (I should say extraction) process.
Now, if you don't want to create a Flex project just for this, you can extract the SWF yourself. The SWC file format is just a Zip containing a SWF and an XML file describing the content. You can then load dynamically this extracted SWF file using a Loader and setting the correct Application Domain. Here's a snippet of my sample project.
public class Web extends Sprite
{
public function Web()
{
//you will not be able to instantiate classes of your library until it's loaded
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("library.swf"), new LoaderContext(false, ApplicationDomain.currentDomain));
}
protected function onLoadComplete(event:Event):void
{
//here you can create instances of classes defined in your library
new Asset();
}
}
You might think that's a pretty tedious job to unzip+copy every time your designers update the library. You could automate this process with a script or an Ant file. Unfortunately, unless I'm missing something, it looks like Flash Builder doesn't want you to extend your build process, so you will still need a bit of hand work or completely convert to Ant (or something similar) to build.
Good luck!
From the moment the SWC is added to your Library, you should be able to access the SWC's assets by directly calling their specific class names . There's no need to try to get a SWF and load it with the Loader class. This actually defeats the purpose of using a SWC in the first place!
Let's say that , in your SWC, you have a MovieClip with a class name of GraphicAsset, to create a new instance , you simply do this:
var mc:MovieClip = new GraphicAsset();
In FB4's folder structure , have a look at your SWC in the Referenced Libraries folder & check the default package, you should see a list of all your assets.