-
Notifications
You must be signed in to change notification settings - Fork 23
Projector
All about projectors or static binaries.
A projector allow you to build your ActionScript 3.0 source code into a portable one-file binary and deploy it by just copying it to the target machine.
The binary only dependency is libc (or msvcrt) and doesn't require Redtamarin to be installed on the machine.
Redtamarin projectors support the following architectures
- Windows 32-bit (win32)
- Windows 64-bit (win64)
- Mac OS X 32-bit (darwin-i386)
- Mac OS X 64-bit (darwin-amd64)
- Linux 32-bit (i386)
- Linux 64-bit (amd64)
Other names for "projector"
- static binary
- fat binary
- one-file binary
- standalone executable
- independent executable
- no-dependencies executable
- self-running executable
- self-contained executable
So, what is a projector really?
It is simply a runtime that embed pre-compiled code and run it by default.
In our case the runtime can be any redshell executable
and pre-compiled code can be any ABC or SWF files using the Redtamarin API.
Q: Do I have to compile the AS3 code?
A: yes, if you want to run AS3 without compiling the code
see shell scripts
A: no, since redtamarin v0.4.2 you can build projectors with plain text .as
files
Q: Can I embed multiple AS files?
A: no, you will have to merge the .as
files into one file
Q: Can I embed only one ABC file?
A: yes
Q: Can I embed multiple ABC files?
A: yes, by combining them in one SWF file
Q: Can I embed multiple SWF files?
A: no
Q: Can I embed a Flash produced SWF file?
A: not with the redshell projectors,
yes with the Flash Standalone projectors
A: yes since redtamarin v0.4.2 with the Program.start( "MainClassName" )
method
and yes with the Flash Standalone projectors
Q: Do I need Visual Studio or GCC installed?
A: no
The term Projector comes from Flash, in fact you could often see it referred as a "Flash Projector".
It started with a feature in Adobe Flash Professional which allowed to export a SWF as an executable, later Adobe provided a Standalone Flash Player with the option to "Create Projector...".
Later, numerous softwares emerged to save swf as exe, see SWF2EXE software.
For a time, Adobe considered removing the feature
The Export Projectors feature was deprecated in Flash Professional CC June 2013 release,
and has been re-enabled in Flash Professional CC June 2014 release even if the feature was still there in the Standalone Flash Player runtime.
While the feature was disabled, a "Export as Projector" extension for Flash Pro CC was created.
See
-
Archived Flash Player versions
to find old Standalone Flash Players from v2 to v20 and most recent. - Flash Professional Help / Exporting Projector files
- Export as Projector from Flash Pro CC
From the Flash Professional Help / Exporting Projector files here how Adobe describe it
About Projectors Projectors are Flash files that contain both the published SWF and Flash Player.
Projectors can play like a normal application, without the need for a web browser,
the Flash Player plugin, Adobe AIR, or any other platform runtimes.Flash Pro CC allows you to publish Projectors for Windows and MAC operating systems.
When exported, a Projector file is generated as.exe
for Windows and.app
for MAC.
You have in general 2 ways to produce a projector (officially)
Flash Professional CC
- select "Commands"
- then "Export as Projector"
Standalone Flash Player
- open a SWF file
- select "File"
- then "Create Projector..."
Manually with Mac OS X
- copy
Standalone Flash Player.app
- option click the
.app
- select "Show Package Contents"
- in the path
Contents/Resources/
- drop a swf file named "movie.swf"
From that point opening "Standalone Flash Player.app" will automatically play this "movie.swf".
Yes, you can rename the .app
to anything you want and also change the icon.
The one thing missing in all that is the support for Linux projectors, even if it is technically possible to take a Linux Standalone Flash Player and create a projector.
The simpler approach was to use the -exe
option provided in the ActionScript Compiler (ASC).
If you created an .abc
file this way
$ java -jar asc.jar -AS3 -import builtin.abc -import shell_toplevel.abc program.as
then you could simply create a projector that way
$ java -jar asc.jar -AS3 -import builtin.abc -import shell_toplevel.abc -exe redshell program.as
Here the option "documentation"
-exe <avmplus path> = emit an EXE file (projector)
But there are a couple of issues with this way of doing.
With ASC you can only create a projector when you're compiling .as
sources to build one .abc
,
if you already have an .abc
file or need to produce a projector from a .swf
file it will not work.
In the Adobe Flex SDK, then the Apache Flex SDK, you have the ActionScript Compiler that we refer as ASC.
This one always had an option to produce a projector
-exe <avmplus path> = emit an EXE file (projector)
You can see how it is implemented in Java by reading
/src/macromedia/asc/embedding/Compiler.java
see the createProjector()
function.
It's nice it's there, but technically we don't need it to be supported by the compilers.
In fact, the only support we need is inside the runtime, if the runtime support projectors then we can build our own "projector compiler".
If you compile Redtamarin with the AVMSHELL_PROJECTOR_SUPPORT
flag,
the runtime will be able to access 2 functions: executeProjector()
and isValidProjectorFile()
.
It works like that
- while the
redshell
starts up - it will search for a "magic number" in the executable file
- if this magic number is found
- then the redshell knows it is a projector
- and then knows where to read a "content length"
- so the redshell can extract the file embedded
here the structure of a projector
| executable bytes | abc bytes | projector header |
The "projector header" is a fixed length of 8 bytes
4 bytes of "magic number, and 4 bytes of "content length"
| projector header |
|
|_ magic number = 0x56 0x34 0x12 0xFA
|_ content length = LEN | LEN<<8 | LEN<<16 | LEN<<24
0x56 0x34 0x12 0xFA
?
is the dword 0xFA123456
in Little Endian (least significant byte first)
In ActionScript 3.0 it would be
//projector signature
var header:ByteArray = new ByteArray(); //always 8 bytes
header.writeByte( 0x56 );
header.writeByte( 0x34 );
header.writeByte( 0x12 );
header.writeByte( 0xFA );
header.writeByte( file_len & 0xFF );
header.writeByte( (file_len>>8) & 0xFF );
header.writeByte( (file_len>>16) & 0xFF);
header.writeByte( (file_len>>24) & 0xFF );
How do we get the "content length" ?
- read the last 8 bytes
- check the first 4 bytes
equals the "magic number"0x56 0x34 0x12 0xFA
- the following 4 bytes
is the "content length"
How do we extract the content from a projector ?
- read the last 8 bytes
- check the first 4 bytes
equals the "magic number"0x56 0x34 0x12 0xFA
- from the following 4 bytes
get the "content length" - from the end of the executable minus 8 bytes,
read the content length to obtain a file
In a projector, the embedded file can either be a SWF or an ABC file,
there to validate the file we then check another "magic number"
which can be either 0x53 0x57 0x46 (SWF)
or 0x53 0x57 0x43 (SWC)
for a SWF file
or something like v = 46<<16|16
(another kind, more complicated) for an ABC file.
As long as the redshell
can detect those "magic numbers" then it can support projectors.
see
-
src/utils/abcdump.as
how to read anuint
and recognise an ABC or SWF/SWC magic number. -
src/core/AbcParser.cpp
AbcParser::canParse()
detection of the ABC magic number. -
src/shell/ShellCore.cpp
ShellCore::executeProjector()
andShellCore::isValidProjectorFile()
detection and validation of a projector magic number.
Because we own the source code of the runtime we can also change the way a projector is detected.
In the 0.4.2 release we changed the length of the projector header.
Now we use 12 bytes
instead of 8 bytes
.
TODO (more explanations)
and link to difference example of AS3 source code to detect different magic numbers
see
redbean
TODO
Other languages use more or less the same principle, here a non-exhaustive list compared to our own redtamarin projectors.
Language | Tool | Open Source | Comment |
---|---|---|---|
PHP | php2exe | yes | support only Windows, need Visual Studio installed |
PHP | bamcompile | yes | support only Windows, may need extra DLL |
Python | py2exe | yes | support only Windows |
Python | exxo | yes | support only Linux 64-bit (x86_64) |
Python | pyinstaller | yes | |
Ruby | ocra | yes | support only Windows, may need extra DLL |
Ruby | RubyScript2Exe | yes | support only Windows and Linux, Mac OS X is experimental |
Note: our focus is only on command-line executable, but other tools provide GUI projectors.