Script CODESYS boot application export for many devices

6 min read · Published November 5, 2026

The ScriptEngine call create_boot_application writes the .app and .crc pair, 2 files, while Export -> Bootproject and firmware (SD Card) adds FIRMWARE, USERDATA, SDCARD.INI, Version and Version.txt.sig. Treat the script as the boot-file step, verify each folder against a 7-entry reference set, and drive a project with 30-plus devices from a hand-written application-to-folder list.

Scripting a CODESYS job with Python goes well until the folder a script leaves behind does not match the folder the menu command makes. That gap is the whole subject here. create_boot_application on the Application object is one documented step that writes the .app and .crc pair; Export -> Bootproject and firmware (SD Card) writes that pair plus FIRMWARE, USERDATA, SDCARD.INI, Version and Version.txt.sig. Treat the script as the boot-file step and keep the card build on its own path. This page draws the line between the two operations, gives the file-count check that verifies every run, and shows the application-to-folder list that keeps a project with 30-plus devices from mixing its exports.

Why does my script make only two files when the menu export makes the whole card?

The two calls are different jobs: create_boot_application writes the boot application pair, the .app file and its .crc checksum, while Export -> Bootproject and firmware (SD Card) writes that pair plus five more entries: FIRMWARE, USERDATA, SDCARD.INI, Version and Version.txt.sig.

The script is not failing. create_boot_application is the ScriptEngine call for building a boot application, and a boot application is the .app file with its .crc checksum. The command you reach by right-clicking the Application object is a different operation. It collects the boot pair and adds the firmware and card files a panel needs in order to start from a card. Two different jobs leave two different folders, and the table further down is the whole difference in one view.

Can ScriptEngine run Export -> Bootproject and firmware (SD Card) directly?

No. The scripting documentation names create_boot_application on the Application object for the boot files, and it names no call for the full card export. Script the pair and keep the card build on its documented path.

The ScriptEngine help states that every object and command CODESYS provides for scripting lives in the scriptengine module. The module is therefore the complete menu of what a script can reach, and the card export is not on it. A script that drives the CODESYS window click by click is not a ScriptEngine feature; it has no documented contract and breaks with the next interface change. Keep the full export where it runs today. Watch the scripting release notes when you move CODESYS versions, because new scripting calls are announced there version by version.

What does create_boot_application actually write?

Two files: the .app boot application and the .crc checksum beside it. That is why a folder holding exactly 2 files after a run is a successful boot-file step and nothing more.

A login download starts the application on a running runtime from the engineering station. The boot pair instead lets a panel start the application from its own storage. That is the job the script does, and it stops there.

Operation Folder after the run Where it runs
create_boot_application (ScriptEngine) .app and .crc, 2 files Python in the ScriptEngine
Export -> Bootproject and firmware (SD Card) (menu) the pair plus FIRMWARE, USERDATA, SDCARD.INI, Version, Version.txt.sig, 7 entries Right-click on the Application object

How do you tell which operation produced a folder?

The folder contents decide it. 2 files mean the scripted step ran. The full card set from the table above means the interactive export ran and the card is ready to test on a panel.

  • Only the pair in the folder: the scripted step ran. Nothing failed inside the call; the export never ran, and the card set is missing.
  • The full set in the folder: the interactive export produced it. The script contributed nothing here.
  • Several devices landing in one folder: the run walked a single name search. Past about 30 devices the names repeat. Stop the loop and build the explicit list in the next section.
  • projects.primary.find returns nothing: the primary project is not the one you think is open, or no object in the tree matches the name. Check both before the loop runs.

How do you verify a scripted export before it touches a panel?

Run both operations once for one device and compare folders entry by entry. The script folder must hold 2 files, the reference folder must hold the full card set, and that recorded set becomes the acceptance test for every later run.

  1. Pick one device. Run Export -> Bootproject and firmware (SD Card) for it into a reference folder and record every entry in that folder. Your record is the master list for your firmware.
  2. Run the script for the same application into a second folder.
  3. Count both folders. The script folder must hold the pair, .app and .crc; the reference folder must match the master list entry for entry.
  4. Put one card or one boot set into a real panel before you repeat the run across the project; a file count alone is not proof the runtime accepts the package.
  5. Keep the master list and the reference folder with the release, so every later run checks against the same record.

How do you stop 30-plus devices from mixing up their exports?

Write the application-to-folder list by hand before any script runs: one line per device with its application object and its own output folder. A name that repeats across 30 devices can then never send one export into another device's folder.

projects.primary.find('Application', True) searches by name. In a large project many applications carry the same name, so a name search cannot say which device a match serves. Write the mapping first, walk it in the script, and stop with an error if two lines resolve to the same object; a silent mismatch is exactly what mixes folders. If the same visualization ships to every panel, keep one reusable screen set, as in the article on reusable HMI screens for multiple devices.

# The documented calls, as used from the ScriptEngine:
application = projects.primary.find('Application', True)
application.create_boot_application(...)  # keep the argument set that already works in your project

# Illustrative check after the run. The folder path below is yours;
# drive the loop from a list of (device, folder) string pairs.
import os
files = os.listdir('D:/boot/mix_1')              # a list of file-name strings
assert len(files) == 2                           # the .app and .crc pair
assert any(f.endswith('.app') for f in files)
assert any(f.endswith('.crc') for f in files)

Run that count in the Python that runs your script, or read the folder in the file manager; the expected result is the same either way. A folder holding anything but the pair points straight at the list line that produced it.

What does the example look like with 32 devices?

Take 32 devices, each application named Application. The hand-written list holds 32 lines, the scripted run writes 2 files into each of 32 folders, 64 files in total, and the single interactive export for the pilot device adds a reference folder with 7 entries.

The arithmetic: 32 folders x 2 files = 64 files from the script, and 2 + 5 = 7 entries in the reference folder. A release that once meant 32 passes through the export dialog now means 1 interactive pass, the pilot, plus one scripted loop over the list. The end check reads the same every time: 32 folders each holding the pair, 1 reference folder matching the master list, and 1 panel checked on real hardware before the remaining 31 devices receive their boot files.

When should you still run the SD-card export by hand?

Run it by hand whenever a folder must bring a panel up from scratch. The card needs the full export set, the 5 entries beyond the .app and .crc pair, and that job stays in the menu or in the panel vendor's update tool.

Only the export produces the runtime and card files a fresh panel needs. Vendors that ship an update tool often fold the job into it, commonly as a Copy Project to SD Card or Copy Project to USB Memory step. If the menu item refuses to run at all, the causes sit elsewhere; why create boot application is grayed out in CODESYS walks that failure.

Recommendation: script create_boot_application for every device through a hand-written application-to-folder list, accept a folder only when it holds the .app and .crc pair, keep one interactive Export -> Bootproject and firmware (SD Card) per release as the 7-entry reference, and check one panel on real hardware before the rest of the project receives its files. For a handful of devices, skip the script; the menu export per device is faster than maintaining the list.

Questions

Does create_boot_application do the same job as a login download?

No. A login download connects to a device, sends the active project to its runtime and starts the application from the engineering station. create_boot_application works on the project and writes the .app and .crc pair for the panel to use at its next start; it never connects to a device. Plan the two as separate steps of a release.

Is the five-entry card set identical for every firmware version?

Treat FIRMWARE, USERDATA, SDCARD.INI, Version and Version.txt.sig as the set observed in working exports, then make your own first interactive export the authority. Record its entries, keep the reference folder with the release, and check every later folder against that record, because file sets can differ between firmware versions.

Can one card update a running panel and also provision a fresh one?

Decide per job. A panel already running the matching runtime starts from the .app and .crc pair; a card for a fresh panel carries the full export set with FIRMWARE. Script the pair for the updates you repeat, and build full card folders through the export, one reference card per release.

Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.

Keep reading

Build your signAsk for a quote