actionscript-3flashairadobeflashdevelop

Attempting to convert SWF to standalone EXE in AIR with FlashDevelop


This problem has been bugging me for a while now, I'm trying to make a standalone EXE from a SWF of a game I'm making, but I've had tons of trouble during the way. I want it standalone, meaning no installer, I want the user to be able to open the EXE and start playing automatically. I'm using FlashDevelop's AIR AS3 Projector Project and have gotten almost all the kinks out, but there's still a snag I'm hitting in the end. I've been able to build the EXE, but upon launch attempt I'm hit with an error that reads: "This application requires a version of Adobe AIR which cannot be found." I've ensured both my AIR project and game project are using AIR version 17, but it's still not working.

I'll provide the code for the bats below and hopefully someone can figure this out.

Packager.bat

@echo off

:: Set working dir
cd %~dp0 & cd ..

if not exist %CERT_FILE% goto certificate

:: AIR output
if not exist %AIR_PATH% md %AIR_PATH%
set OUTPUT=%AIR_PATH%\%AIR_NAME%%AIR_TARGET%.air

:: Package
echo.
echo Packaging %AIR_NAME%%AIR_TARGET%.air using certificate %CERT_FILE%...
adt -package -keystore bat\TheLabyrinth.p12 -storetype pkcs12 -target bundle The_Labyrinth application.xml -C bin TheLabyrinth.swf TheLabyrinthGame.swf lib\backgrounds\cobblestone.png lib\backgrounds\frameBackground.png lib\backgrounds\fullscreenCobble.png lib\backgrounds\parchment.png lib\backgrounds\parchmentFrameBackground.png lib\spritesheet.png
call adt -package %OPTIONS% %SIGNING_OPTIONS% %OUTPUT% %APP_XML% %FILE_OR_DIR%
if errorlevel 1 goto failed
goto end

:certificate
echo.
echo Certificate not found: %CERT_FILE%
echo.
echo Troubleshooting: 
echo - generate a default certificate using 'bat\CreateCertificate.bat'
echo.
if %PAUSE_ERRORS%==1 pause
exit

:failed
echo AIR setup creation FAILED.
echo.
echo Troubleshooting: 
echo - verify AIR SDK target version in %APP_XML%
echo.
if %PAUSE_ERRORS%==1 pause
exit

:end
echo.

Application.xml

<?xml version="1.0" encoding="utf-8" ?> 
<application xmlns="http://ns.adobe.com/air/application/17.0">

    <id>TheLabyrinth</id> 
    <versionNumber>1.0</versionNumber> 
    <filename>TheLabyrinth</filename> 

    <name>The Labyrinth</name> 
    <description></description> 
    <copyright></copyright> 

    <initialWindow> 
        <title>The Labyrinth</title> 
        <content>TheLabyrinth.swf</content> 
        <systemChrome>standard</systemChrome> 
        <transparent>false</transparent> 
    <visible>true</visible> 
    <minimizable>true</minimizable> 
    <maximizable>true</maximizable> 
    <resizable>true</resizable> 
</initialWindow> 

<!-- 
More options:
http://livedocs.adobe.com/flex/3/html/File_formats_1.html#1043413
-->
</application>

Thanks for any help regarding this, I've searched far and wide for an answer and I've yet to come across a fix.


Solution

  • Okay, I forgot about this question but I'm coming back to answer it in case anyone else stumbles upon it. Whenever using FlashDevelop with the intent of creating a standalone executable, I choose the AIR AS3 Projector when creating a new project. This will already contain the batch files you're going to need to change using my files below (I'll also show any unique changes you need to make). From there here are the settings for the batch files that I copy over from a previous project that works.

    First I'll show the application.xml since that has a few things we want to check out beforehand. The settings will automatically populate in this xml when you launch your program in either Debug or Release mode. This specific example is from a game titled Charlene for my girlfriend:

    <?xml version="1.0" encoding="utf-8"?>
    <application xmlns="http://ns.adobe.com/air/application/21.0">
        <id>Charlene</id>
        <versionNumber>1.0</versionNumber>
        <filename>Charlene</filename>
        <name>Charlene</name>
        <initialWindow>
            <title>Charlene</title>
            <content>Charlene.swf</content>
            <systemChrome>standard</systemChrome>
            <transparent>false</transparent>
            <visible>true</visible>
            <minimizable>true</minimizable>
            <maximizable>false</maximizable>
            <resizable>false</resizable>
            <x>0</x>
            <y>0</y>
            <minSize>800 800</minSize>
        </initialWindow>
        <!-- 
        More options:
        http://livedocs.adobe.com/flex/3/html/File_formats_1.html#1043413
        -->
        <supportedProfiles>extendedDesktop</supportedProfiles>
        <android>
            <manifestAdditions><![CDATA[<manifest android:installLocation="auto" xmlns:android="http://schemas.android.com/apk/res/android" />]]></manifestAdditions>
        </android>
    </application>
    

    There are two things to note here: the application xmlns version MUST be the same version as the AIR version you're using (this can be viewed by clicking Project, and then Properties). If this is not the same version, simply change either the xml or the version in the Properties otherwise your program won't compile.

    The next thing to note is the supportedProfiles. The extendedDesktop setting is required if you want the keyboard to work while your program is in fullscreen.

    Now we're going to look at CreateCertificate.bat. You need to run this batch file before any others, as the compiler needs a certificate to package your program. This will create a unique key for your program with the name "YourProgramTitle.p12":

    @echo off
    
    :: Set working dir
    cd %~dp0 & cd ..
    
    set PAUSE_ERRORS=1
    call bat\SetupSDK.bat
    call bat\SetupApp.bat
    
    :: Generate
    echo.
    echo Generating a self-signed certificate...
    call adt -certificate -cn %CERT_NAME% 2048-RSA %CERT_FILE% %CERT_PASS%
    if errorlevel 1 goto failed
    
    :succeed
    echo.
    echo Certificate created: %CERT_FILE% with password "%CERT_PASS%"
    echo.
    if "%CERT_PASS%" == "fd" echo Note: You did not change the default password
    echo.
    echo HINTS: 
    echo - you only need to generate this certificate once,
    echo - wait a minute before using this certificate to package your AIR application.
    echo.
    goto end
    
    :failed
    echo.
    echo Certificate creation FAILED.
    echo.
    
    :end
    pause
    

    No special settings here, moving on to the PackageApp.bat. This is another batch that doesn't require specific changing, the settings here should work for compiling your project:

    @echo off
    
    :: Set working dir
    cd %~dp0 & cd ..
    
    set PAUSE_ERRORS=1
    call bat\SetupSDK.bat
    call bat\SetupApp.bat
    
    set AIR_TARGET=air/Setup.exe
    ::set AIR_TARGET=-captive-runtime
    set OPTIONS=-tsa none
    call bat\Packager.bat
    
    pause
    

    Next up is the big one, Packager.bat. Again, no special settings here, this batch file should be good to copy over and not change:

    @echo off
    
    :: Set working dir
    cd %~dp0 & cd ..
    
    if not exist %CERT_FILE% goto certificate
    
    :: AIR output
    if not exist %AIR_PATH% md %AIR_PATH%
    set OUTPUT=-target bundle %AIR_NAME%
    
    :: Package
    echo.
    echo Packaging %AIR_NAME%%AIR_TARGET%.air using certificate %CERT_FILE%...
    call adt -package %OPTIONS% %SIGNING_OPTIONS% %OUTPUT% %APP_XML% %FILE_OR_DIR%
    if errorlevel 1 goto failed
    goto end
    
    :certificate
    echo.
    echo Certificate not found: %CERT_FILE%
    echo.
    echo Troubleshooting: 
    echo - generate a default certificate using 'bat\CreateCertificate.bat'
    echo.
    if %PAUSE_ERRORS%==1 pause
    exit
    
    :failed
    echo AIR setup creation FAILED.
    echo.
    echo Troubleshooting: 
    echo - verify AIR SDK target version in %APP_XML%
    echo.
    if %PAUSE_ERRORS%==1 pause
    exit
    
    :end
    echo.
    

    Next up is RunApp.bat. There's not much here but I'll include it anyway:

    @echo off
    
    :: Set working dir
    cd %~dp0 & cd ..
    
    set PAUSE_ERRORS=1
    call bat\SetupSDK.bat
    call bat\SetupApp.bat
    
    echo.
    echo Starting AIR Debug Launcher...
    echo.
    
    adl "%APP_XML%" "%APP_DIR%"
    if errorlevel 1 goto error
    goto end
    
    :error
    pause
    
    :end
    

    You can actually change the echo Starting AIR Debug Launcher... line if you want the cmd to show a different message before the debugger launches.

    We're gonna look at the SetupApp.bat. This has some parameters you're going to have to change to fit your program:

    :: Set working dir
    cd %~dp0 & cd ..
    
    :user_configuration
    
    :: About AIR application packaging
    :: http://livedocs.adobe.com/flex/3/html/help.html?content=CommandLineTools_5.html#1035959
    :: http://livedocs.adobe.com/flex/3/html/distributing_apps_4.html#1037515
    
    :: NOTICE: all paths are relative to project root
    
    :: Your certificate information
    set CERT_NAME="Charlene"
    set CERT_PASS=fd
    set CERT_FILE="bat\Charlene.p12"
    set SIGNING_OPTIONS=-storetype pkcs12 -keystore %CERT_FILE% -storepass %CERT_PASS%
    
    :: Application descriptor
    set APP_XML=application.xml
    
    :: Files to package
    set APP_DIR=bin
    set FILE_OR_DIR=-C %APP_DIR% .
    
    :: Your application ID (must match <id> of Application descriptor) and remove spaces
    for /f "tokens=3 delims=<>" %%a in ('findstr /R /C:"^[  ]*<id>" %APP_XML%') do set APP_ID=%%a
    set APP_ID=%APP_ID: =%
    
    :: Output
    set AIR_PATH=air
    set AIR_NAME=Charlene
    
    :validation
    findstr /C:"<id>%APP_ID%</id>" "%APP_XML%" > NUL
    if errorlevel 1 goto badid
    goto end
    
    :badid
    echo.
    echo ERROR: 
    echo   Application ID in 'bat\SetupApp.bat' (APP_ID) 
    echo   does NOT match Application descriptor '%APP_XML%' (id)
    echo.
    if %PAUSE_ERRORS%==1 pause
    exit
    
    :end
    

    Here, the set CERT_NAME="Charlene" line should have the string name that's equal to the name parameter in the application.xml. The set CERT_FILE="bat\Charlene.p12" file name should be the same name your CreateCertification.bat created when you ran it (run it now if you haven't). set AIR_NAME=Charlene should again have the same name as the CERT_NAME (assuming you want your finished project to have the same name as your debugged one).

    Lastly we're going to look at the SetupSDK.bat. This one has one line you're going to have to change:

    :: Set working dir
    cd %~dp0 & cd ..
    
    :user_configuration
    
    :: Static path to Flex SDK
    set FLEX_SDK=C:\Users\Alec\AppData\Local\FlashDevelop\Apps\flexairsdk\4.6.0+21.0.0
    
    :: Use FD supplied SDK path if executed from FD
    if exist "%FD_CUR_SDK%" set FLEX_SDK=%FD_CUR_SDK%
    
    :validation
    if not exist "%FLEX_SDK%\bin" goto flexsdk
    goto succeed
    
    :flexsdk
    echo.
    echo ERROR: incorrect path to Flex SDK in 'bat\SetupSDK.bat'
    echo.
    echo Looking for: %FLEX_SDK%\bin
    echo.
    if %PAUSE_ERRORS%==1 pause
    exit
    
    :succeed
    set PATH=%FLEX_SDK%\bin;%PATH%
    

    set FLEX_SDK should have the path to your Flex+AIR SDK. If you need to know the path, click the Project tab, then Properties, navigate to the SDK tab, click Manage, click the Installed Flex SDKs parameter, click the ellipses square on the right side of the InstalledSDK[] Array, make sure you've selected the most current version of the SDK on the left Members side (or the one that has the same version as your application.xml file), expand the window and you should see the path under the Location field.

    Okay, it's been a long road. Test your project to make sure your local swf is updated, then run the PackageApp.bat. If everything was set up properly there should be no errors and after a few second the cmd will say "Press any key to continue" and a new folder with the name of your project should appear in your project's directory. This folder should contain another folder called Adobe AIR, a lib folder, a META-INF folder, an exe with your project's name, an swf with your project's name, and a mimetype file. You should be able to run the exe with no issue. And there you have it! Hopefully this works for anyone else with this problem.

    Just a quick note: I noticed when packaging relatively large projects, sometimes the batch files don't compile a full project. It can take many attempts before it compiles fully, but I found a cheat. It requires an already existing, fully compiled project. All you need to do is copy over your project's swf (normally housed in your bin folder) over to the packaged project's folder. You may also need to copy over other files if you've changed them, such as the application.xml (the compiled file is located in the META-INF\AIR directory), or the lib folder if you import anything during run-time. This lets you bypass recompiling!