Creating Win32 Desktop Apps

This guide outlines how to configure and build a Win32 desktop app via the Corona Simulator. A Corona-built Win32 desktop app consists of a .exe file, a collection of .dll files, and your Corona project’s asset files. It is compiled for 32-­bit which can run on both 32­-bit and 64­-bit Windows desktop operating systems.

System Requirements

Notes
  • All features supported by the Corona Simulator for Windows are supported for Win32 desktop builds. However, the Corona Simulator for Windows does not support most native UI features that the macOS version does.

  • Just like mobile device builds, Win32 desktop builds support an orientation table within the project’s build.settings file. If defined, the width and height defined in the config.lua file (guide) will be relative to portrait orientation, just like iOS and Android. This means that for a landscape-oriented app, width is the height of the window and height is the width of the window, making your project settings portable to both desktop and mobile devices.

Win32 Platform Settings

Corona’s build.settings file supports the following Win32 platform-specific settings via the win32 table:

settings =
{
    win32 =
    {
        -- Settings for Win32 apps go here
    }
}
preferenceStorage

Indicates where the app’s custom preferences should be stored when accessed via the system.getPreference(), system.setPreferences(), and system.deletePreferences() functions using the "app" category.

settings =
{
    win32 =
    {
        preferenceStorage = "registry",
    }
}

This key can be set to one of the following:

  • "sqlite" — This is the default setting and the most portable option. Preferences are stored to a CoronaPreferences.sqlite database file under the Windows user’s hidden .\AppData\Local\<CompanyName>\<AppName>\.system directory.
  • "registry" — Stores the app’s preferences to the Windows registry under HKEY_CURRENT_USER\Software\<CompanyName>\<AppName>. This feature has portability issues, for example preference names are not case-sensitive when stored to the registry. Also, forward slashes (/) and backslashes (\) in a preference name will be regarded as registry key path separators and will be treated as the same characters.
singleInstance

Set this to true (the default setting) to allow only one instance of a Win32 desktop application to exist at a time. This means that attempting to launch a second instance will bring the first instance’s window to the front of the desktop instead. If the second instance was given any command line arguments, those arguments are delivered to the first instance via an "applicationOpen" typed system event. Set this setting to false to support multiple application instances at the same time.

settings =
{
    win32 =
    {
        singleInstance = false,
    }
}

Window Settings

For both Win32 desktop apps and macOS desktop apps, Corona’s build.settings file supports a window table for customizing the app’s desktop window, including the default width/height, the title of the window, and more.

settings =
{
    window =
    {
        -- Settings for the desktop window; applies to both Win32 and macOS desktop apps
    },
}

Within the window table, the following settings are supported:

defaultMode

Sets how the window should be launched on startup. Supported values include "normal", "minimized", "maximized", or "fullscreen". Default is "normal". This can also be set programmatically via the native.setProperty() API.

settings =
{
    window =
    {
        defaultMode = "fullscreen",
    },  
}
defaultViewWidth

Sets the default launch width of the view/client area of the window. This is the region within the borders of the window to which Corona renders. Ideally, this should match or exceed your config.lua content area width.

settings =
{
    window =
    {
        defaultViewWidth = 640,
    },  
}
defaultViewHeight

Sets the default launch height of the view/client area of the window. This is the region within the borders of the window to which Corona renders. Ideally, this should match or exceed your config.lua content area height.

settings =
{
    window =
    {
        defaultViewHeight = 960,
    },
}
resizable

Set this to true to allow the end user to resize the window (the window is not resizable by default). Note that if true, you may need to handle Corona’s resize event to re-layout your content.

settings =
{
    window =
    {
        resizable = true,
    },
}
minViewWidth

This setting only applies if resizable is set to true. Prevents the user from resizing the window to a width smaller than this value. Note that this represents the width of the region within the borders of the window. If resizable is set to true and this setting is not specified, the window can be resized down to whatever width the OS allows.

settings =
{
    window =
    {
        minViewWidth = 320,
    },
}
minViewHeight

This setting only applies if resizable is set to true. Prevents the user from resizing the window to a height smaller than this value. Note that this represents the height of the region within the borders of the window. If resizable is set to true and this setting is not specified, the window can be resized down to whatever height the OS allows.

settings =
{
    window =
    {
        minViewHeight = 480,
    },
}
enableCloseButton

Enables or disables the window’s “close” button (enabled by default). If disabled, you must close the window in Lua via native.requestExit(). Note that Corona does not currently trigger an event when the “close” button is clicked.

settings =
{
    window =
    {
        enableCloseButton = true,
    },
}
enableMinimizeButton

Enables or disables the window’s “minimize” button (enabled by default).

settings =
{
    window =
    {
        enableMinimizeButton = true,
    },
}
enableMaximizeButton

Enables or disables the window’s “maximize” button (disabled by default). Note that the window will be resized when maximized/restored, so if this setting is true, you may need to handle Corona’s resize event to re-layout your content.

settings =
{
    window =
    {
        enableMaximizeButton = true,
    },
}
suspendWhenMinimized

Tells the runtime to suspend when the window is minimized (disabled by default).

settings =
{
    window =
    {
        suspendWhenMinimized = true,
    },
}
titleText

Sets the window’s title bar text to the specified string (no title bar text by default). Supports 2-letter ISO 639‐1 language codes and optional 2-letter ISO 3166‐1 country codes (neither case sensitive). The title text can also be set programmatically via the native.setProperty() API.

settings =
{
    window =
    {
        titleText = {
            -- The "default" text will be used if the system is using a language and/or
            -- country code not defined below. This serves as a fallback mechanism.
            default = "Window Title Test",
            -- This text is used on English language systems in the United States.
            -- Note that the country code must be separated by a dash (-).
            ["en‐us"] = "Window Title Test (English‐USA)",
            -- This text is used on English language systems in the United Kingdom.
            -- Note that the country code must be separated by a dash (-).
            ["en‐gb"] = "Window Title Test (English‐UK)",
            -- This text is used for all other English language systems.
            ["en"] = "Window Title Test (English)",
            -- This text is used for all French language systems.
            ["fr"] = "Window Title Test (French)",
            -- This text is used for all Spanish language systems.
            ["es"] = "Window Title Test (Spanish)",
        },
    },
}

Excluding Files

You can exclude file(s) that aren’t needed for a Win32 desktop app via the build.settings file’s excludeFiles pattern matching feature. Please see the Excluding Files section of the Project Build Settings guide for more details on pattern matching.

App Icon

You must add a Icon­-win32.ico file to your Corona project’s root directory when doing a Win32 build via the Corona Simulator. This file should contain multiple images at different resolutions, bundled into a single .ico file (details). This Icon­-win32.ico file will be used to set the icon for the following:

  1. The icon that your .exe file uses, as viewed in Windows Explorer.
  2. The icon used by your app’s desktop window (top-left corner).
  3. The icon used by your app on the Windows taskbar.
Note

You can use Windows Explorer to see how your .exe app icon looks at different resolutions — simply choose different “View” modes in its menu/toolbar such as “Details” or “Tiled.”

Building / Running

To build and run your Win32 desktop app, follow these steps:

  1. Open the Corona Simulator.
  2. Open and run a Corona project.
  3. Select the FileBuildWindows… menu item.
  1. The Application Name, EXE File Name, Version, and Save to Folder fields are all required. All other fields are optional, but we highly recommend that you specify them. Here are notes regarding these build dialog fields:

    • Application Name — The application name you’ve entered can be fetched at runtime via Corona’s system.getInfo( "appName" ) call (reference).

    • EXE File Name — When right-clicking the built .exe file, most of this field information can be seen via the “Properties” window.

    • Version — The version string you’ve entered can be fetched at runtime via Corona’s system.getInfo( "appVersionString" ) call (reference).

    • Description — This string is used by the Windows Task Manager to display the name of your app process. If the description is not set, the Task Manager will use the application name instead.

    • Application Name + Company Name — In combination, these are used to generate a unique directory to store your app’s files under the Windows user’s hidden \AppData directory.

Note

When using the above combination, the following directories will be generated:

  • .\AppData\Roaming\<CompanyName>\<AppName>\Documents
  • .\AppData\Local\<CompanyName>\<AppName>\CachedFiles
  • .\AppData\Local\<CompanyName>\<AppName>\TemporaryFiles
  • .\AppData\Local\<CompanyName>\<AppName>\.system  (used by Corona for its own internal purposes)

Windows will automatically synchronize files under the \Roaming folder on to other machines that the user logs into on the same Windows domain via Active Directory. However, files under the \Local folder will not be synchronized.

  1. Click the Build button to build your application to the given Save to Folder location.
  1. From the resulting dialog window, click the View in Explorer… button to go to the directory where your built Win32 app was copied to. The application will be under a subfolder named <AppName>.Win32. Open this folder to access the app’s .exe file.

  2. Double click on the .exe file to run your app.

Debugging

The Corona Simulator does not currently support direct simulation of an app running in Windows desktop mode. However, the Windows version of Solar2D contains a new application named Corona.Shell.exe which can run a Corona project similarly to how a built Win32 desktop app runs. By default, you can find the Corona Shell application here:

C:\Program Files\Corona Labs\Corona SDK\Corona.Shell.exe

When you run the Corona Shell, it will prompt you to select a Corona project’s main.lua file. Once the file has been selected, it will run the app. This allows you to make quick changes to your project without having to perform a build each time. However, note that the Corona Shell does not support restarts or logging since it’s actually running your project just like a real Win32 desktop app (no simulation).

Also note that when running a built Win32 desktop app or the Corona Shell, all print() output and Lua errors/warnings will be streamed to stdout. There are various ways to manage this output. One way is to redirect stdout to a text file at the command line (MS­DOS box) as shown below. This will launch your app and, after you close it, a text file will be generated containing all of the print/logging information.

[YourExeFileName] > log.txt

Alternatively, you can run the Corona Output Viewer installed under the Windows start menu’s “Solar2D” folder to run a Corona-built Win32 desktop app and monitor its output.

App Signing

The Corona Simulator will n​ot ​digitally sign your built .exe file. This is because Windows does not require .exe files to be digitally signed in order to run them (it’s optional). However, some antivirus software might block your app from being started or “red­ flag” the app if it’s not digitally signed. Thus, it is best to digitally sign your .exe when you’re ready to distribute the app publicly.

Microsoft documents how to digitally sign an application here.

To summarize, in order to sign your app, you need to purchase a digital certificate from a reputable source such as VeriSign or DigiCert. Microsoft’s signing tools require this to be a .pfx file. You’ll then need to acquire Microsoft’s signtool command line utility by downloading and installing one of the following:

Here is an example of how to digitally sign your app:

signtool sign /f <PathToPfxFile> /p <CertificatePassword> /t <TimeServerUrl> <PathToExeFile>