Siemens HMI Toolbox File Explorer: Resolving Folder Copy Failures

David Krause15 min read
HMI / SCADASiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Problem Overview

The Siemens HMI Toolbox for WinCC Comfort/Advanced and the matching runtime libraries on TP, KTP, and Comfort Panels (TP700, TP900, TP1200, TP1500, TP1900, TP2200) ships a configurable File Explorer screen object. The control opens a Windows-Explorer-style user interface on the panel and exposes Copy / Paste / Cut / Delete buttons bound to the runtime's VBScript engine. On every TIA Portal release where the toolbox library has been deployed (V14 SP1 through V20), single-file Copy → Paste operations complete without error, but Pasting a complete directory (or a folder that contains subfolders) fails silently. The destination list view stays blank, no event is written to the panel's diagnostic buffer, and no HMI tag indicates failure.

End users describe the symptom uniformly: "I can't copy folder, copying files working, but folder no." The panel-side storage media (SD card, USB stick, internal flash /storage path) is healthy, file-level copies of the same payload work, and no WinCC event is raised. The defect is in the toolbox, not in the panel's filesystem or in operator error.

Field symptom recap: Original report from a TP900 Comfort Panel running WinCC Runtime Advanced V16 Update 5. File-level copy <CopyFile.bin> succeeds; folder-level copy <\Storage Card\Recipes\TTT\> produces no result in the destination and no log entry.

Affected Platforms and Firmware Versions

The toolbox library is delivered as part of the Toolbox for HMI Projects support package (Siemens support entry ID 106226404). The folder-copy defect is reproduced on every runtime image that hosts the unpatched library:

Panel family Typical model TIA Portal version Runtime image
Comfort Panels 4" TP700 Comfort V14 SP1 – V20 WinCC Comfort V14+
Comfort Panels 7" TP900 Comfort V14 SP1 – V20 WinCC Comfort / Advanced V14+
Comfort Panels 9" TP1200 Comfort V15 – V20 WinCC Comfort / Advanced V15+
Comfort Panels 12" TP1500 Comfort V15.1 – V20 WinCC Comfort / Advanced V15.1+
Comfort Panels 15" TP1900 Comfort V16 – V20 WinCC Comfort / Advanced V16+
Comfort Panels 22" TP2200 Comfort V16 – V20 WinCC Comfort / Advanced V16+
RT Advanced (PC) PC runtime on Win 10 LTSC V15 – V20 WinCC Runtime Advanced V15+
RT Professional (PC) PC runtime on Win Server V16 – V20 WinCC Runtime Professional V16+

Panel firmware images before V14 are not certified for the toolbox; the support entry covers TIA Portal as of the publication date and is updated independently of the runtime bug fixes that have shipped since. Always verify the toolbox revision in the support entry before commissioning a workaround.

Root Cause Analysis

The File Explorer object is implemented as a layered container of screen objects in the toolbox: a list view, a tree view, an action bar, and a VBScript wrapper. The wrapper exposes copy/cut/delete actions through the WinCC scripting runtime. Internally, the wrapper dispatches calls to FileSystemObject via a thin abstraction layer.

Two design choices inside that abstraction layer cause the folder-copy defect:

  1. The wrapper iterates the source selection and calls FileSystemObject.CopyFile for every entry in the selection. The wrapper does not branch on the type of entry (file vs folder), so a directory entry reaches the same call path as a file entry and is rejected by the FSO at runtime.
  2. The wrapper traps the COM error returned by the FSO and discards it without setting an HMI tag, raising a WinCC alarm, or pushing an entry to the diagnostic buffer. From the operator's point of view the operation is silent.

The same defect explains why MoveFile scripts written in plain VBScript against the WinCC runtime also fail on folders. MoveFile is documented as a single-file primitive; it cannot move a directory tree, and the wrapper's UI button hides the limitation from the operator.

The repository where the toolbox stores the File Explorer template and helper scripts is the same one referenced in the HMI files editor entry of the TIA Portal documentation set (Load files using the 'HMI files' editor). The editor is what loads the runtime helper library into the panel image; the runtime then resolves symbols such as FileCopy, MoveFile, and Dir at script-execution time.

Toolbox Function Reference

Before writing a workaround, the engineer must understand the surface area of the VBScript runtime that the WinCC scripting engine exposes. The relevant primitives are documented in the WinCC scripting reference; the subset the workaround depends on is summarized below.

Function Signature Purpose Limitation
FileCopy FileCopy source, destination Copies one file Single file only; cannot copy directories
FileMove / MoveFile FileMove source, destination Moves one file Single file only; cannot move directories
FileDelete FileDelete path Deletes one file Single file; cannot recursively delete a directory tree
Dir Dir[(path[, attributes])] Returns one matching entry; subsequent calls return next Returns file names; separate wildcard needed for directories
FileLen FileLen(path) Returns file size in bytes Returns -1 on directories
GetAttr GetAttr(path) Returns attribute bitmask Bit 16 = directory, bit 32 = archive
MkDir MkDir path Creates a single directory Does not create parents; one call per directory
RmDir RmDir path Removes a single empty directory Cannot remove non-empty directory trees

The crucial observation is that none of the primitives operate on directory trees. Every workaround for the toolbox folder-copy defect must therefore enumerate the source tree manually and call these primitives once per file or once per directory.

Storage Locations and Path Conventions

Comfort Panels expose a small set of fixed storage paths through the WinCC runtime. The workaround scripts must use these canonical paths; absolute Windows-style paths do not resolve.

Logical location Path on Comfort Panel Notes
Internal flash (recipe / persistent) \storage card\ or /tmp/ Battery-backed on TP series
SD card slot (X51) \storage card2\ or /media/simatic/X51/ Removable media; hot-swappable
USB front (X60) \usb\ or /media/simatic/X60/ Operator-side removable media
USB rear (X61) \usb2\ or /media/simatic/X61/ Service / engineering removable media
Network share (PC runtime only) \\server\share\ Not supported on panel firmware
Path syntax. WinCC Runtime scripting accepts both the legacy backslash form (\Storage Card\Recipes\) and the Linux form (/media/simatic/X51/Recipes/) on Comfort Panels, but the legacy form is more portable across the toolbox versions currently in the field. Stick to the legacy form for compatibility.

Scripted Workaround: Recursive Folder Copy

The standard workaround replaces the toolbox's broken Paste action with a VBScript procedure that uses the runtime's Dir primitive to enumerate the source tree and then calls FileCopy once per file and MkDir once per directory. The procedure is bound to a button event in the same screen where the toolbox File Explorer is placed.

Procedure: CopyFolderRecursive

'------------------------------------------------------------
' CopyFolderRecursive - WinCC Comfort / Advanced runtime VBScript
' Copies a folder and all its contents to a destination folder.
' Called from a button "Copy Folder" on the File Explorer screen.
'------------------------------------------------------------
Sub CopyFolderRecursive(ByVal sSource, ByVal sDest)
    Dim sName, sFullSource, sFullDest, sEntry, sRel

    ' Normalize trailing backslash
    If Right(sSource, 1) <> "\" Then sSource = sSource & "\"
    If Right(sDest, 1) <> "\" Then sDest = sDest & "\"

    ' Strip the trailing leaf and create the destination folder
    sName = Mid(sSource, 1, Len(sSource) - 1)
    sName = Mid(sName, InStrRev(sName, "\") + 1)
    sDest = sDest & sName

    EnsureFolderExists sDest

    ' 1. Copy files in this directory
    sEntry = Dir(sSource & "*.*", 0)
    Do While Len(sEntry) > 0
        If (GetAttr(sSource & sEntry) And 16) = 0 Then
            ' bit 16 NOT set -> not a directory
            FileCopy sSource & sEntry, sDest & "\" & sEntry
        End If
        sEntry = Dir()
    Loop

    ' 2. Recurse into subdirectories
    sEntry = Dir(sSource & "*.*", 16)
    Do While Len(sEntry) > 0
        If (GetAttr(sSource & sEntry) And 16) = 16 Then
            CopyFolderRecursive sSource & sEntry, sDest
        End If
        sEntry = Dir()
    Loop
End Sub

Procedure: EnsureFolderExists

'------------------------------------------------------------
' EnsureFolderExists - WinCC Comfort / Advanced runtime VBScript
' Creates a directory if it does not already exist.
'------------------------------------------------------------
Sub EnsureFolderExists(ByVal sPath)
    Dim aParts, i, sBuilt
    If Right(sPath, 1) = "\" Then sPath = Left(sPath, Len(sPath) - 1)
    aParts = Split(sPath, "\")
    sBuilt = aParts(0)
    For i = 1 To UBound(aParts)
        sBuilt = sBuilt & "\" & aParts(i)
        On Error Resume Next
        MkDir sBuilt
        On Error Goto 0
    Next
End Sub

Trigger from the Screen Button

Bind the procedure to a button configured under HMI tags → Events → Click. The button exposes two internal tags that the operator sets before pressing the button:

  • TagSrcFolder (text tag) – absolute source folder path, for example \Storage Card\Recipes\TTT\
  • TagDstFolder (text tag) – absolute destination folder path, for example \Storage Card2\Backup\TTT\
Sub btnCopyFolder_Click(ByVal Item)
    Dim sSrc, sDst
    sSrc = SmartTags("TagSrcFolder")
    sDst = SmartTags("TagDstFolder")
    If Len(sSrc) = 0 Or Len(sDst) = 0 Then
        ShowSystemAlarm "Source and destination folders required."
        Exit Sub
    End If
    CopyFolderRecursive sSrc, sDst
    ShowSystemAlarm "Folder copy completed."
End Sub

Iteration Order and Why Dir Has to Be Called Twice

WinCC's Dir function returns one entry at a time. The first call uses a path and an attribute mask (0 = files only, 16 = directories only) and resets the internal cursor. Subsequent calls without arguments advance the cursor and return the next matching entry. When the cursor is exhausted, Dir returns an empty string. This is why the workaround calls Dir twice in sequence: once to iterate files, then once to iterate subdirectories. Mixing files and directories in a single pass is unreliable because the runtime's attribute mask filter applies to the cursor, not to the path glob.

Workaround: Single-Level Folder Move with MoveFile

If the deployment only needs to move a folder that contains files (no subdirectories), a simpler procedure is sufficient. The source must be on the same storage device as the destination because the runtime's FileMove does not span volumes reliably.

Sub MoveFolderOneLevel(ByVal sSource, ByVal sDest)
    Dim sName, sEntry
    If Right(sSource, 1) <> "\" Then sSource = sSource & "\"
    sName = Mid(sSource, 1, Len(sSource) - 1)
    sName = Mid(sName, InStrRev(sName, "\") + 1)
    EnsureFolderExists sDest & "\" & sName
    sEntry = Dir(sSource & "*.*", 0)
    Do While Len(sEntry) > 0
        FileMove sSource & sEntry, sDest & "\" & sName & "\" & sEntry
        sEntry = Dir()
    Loop
End Sub

The same caveat from the toolbox defect applies: MoveFile is not a folder move primitive. Calling it on a directory fails silently in exactly the same way the toolbox does. The procedure above flattens the move into N file-level MoveFile calls.

Alternative: Deploy a Pre-Built Archive

For deployments that need to ship a directory tree atomically (for example, a recipe set or a parameter bundle), the more reliable approach is to package the directory as a single file on the engineering workstation and use the HMI files editor to copy it to the panel. The HMI files editor is the integration path that the TIA Portal documentation entry on the runtime environment documents explicitly (Load files using the 'HMI files' editor). The editor accepts a single file of any format and drops it onto a configured panel-side path; the runtime then unpacks it through a project-side script.

The unpack procedure follows the same enumeration pattern as the folder-copy workaround, but uses one runtime primitive that the file-level approach does not: a project-side script can be set up to read a ZIP archive using the runtime's binary file I/O APIs. The runtime supports the same Open / Line Input / Print # / Close primitives plus binary access, which is enough to implement a streaming reader against the store method of the central ZIP parser. Most projects instead ship a small extraction helper compiled against the panel runtime that wraps libzip 1.2 or zlib 1.2 and is loaded through the HMI files editor as a DLL / SO. The exact format depends on the panel image; for PC runtime the helper can be a plain Windows DLL.

Adopt the archive approach when the source folder contains more than ~200 files or when a single deployment includes nested directory structures deeper than three levels. The recursive CopyFolderRecursive scales linearly with the entry count but pays a per-file overhead that becomes noticeable on SD-card media above ~1000 entries.

Verification Procedure

  1. Compile the project in TIA Portal V16 (or matching version). Resolve every warning; the recursive procedure in particular must compile without missing-symbol errors.
  2. Download the project to the panel using the HMI files editor and the standard Download to device dialog.
  3. Place a test folder on the panel's internal storage with three subfolders, each containing two files. Note the byte count and CRC of every file before the test.
  4. From the operator screen, set TagSrcFolder to the test folder and TagDstFolder to the destination, then press the Copy Folder button.
  5. Wait for the Folder copy completed system alarm to appear. The runtime's VBScript engine is single-threaded per panel; on a TP900 with a 200-MHz ARM, a folder with 500 files typically completes in 6-12 seconds.
  6. Open the destination on the panel's File Explorer view and confirm every file is present and matches the source byte count. Confirm every subdirectory is present.
  7. Use the engineering station's Online → Accessible nodes view to read the destination via the panel's FTP service (anonymous read access). Compare byte counts file by file.
  8. Repeat the test with the source folder on the SD card and the destination on the USB stick (or vice versa) to confirm cross-volume operation.
  9. Repeat the test with the source folder containing a long path (32 characters or more) to confirm the runtime's path-length handling.
  10. Power-cycle the panel and confirm the destination still exists. The runtime's internal flash is battery-backed; SD card and USB stick contents persist as expected.

Troubleshooting Matrix

Symptom Likely cause Diagnostic Fix
Button click does nothing Event not bound, or procedure name typo Inspect HMI tags → Events → Click on the button Re-bind to btnCopyFolder_Click
System alarm "Source and destination folders required" Tag is empty Read TagSrcFolder and TagDstFolder online Populate both tags before pressing the button
Files copied but subfolders missing Runtime truncated the recursion Check that EnsureFolderExists precedes the recursive call Move EnsureFolderExists to the top of CopyFolderRecursive
Some files missing in destination Filename collisions Enable Overwrite semantics by deleting pre-existing files Pre-clear destination with FileDelete
System alarm "Path not found" during MkDir Parent directory missing or path contains unsupported characters Log the path string with HMIRuntime.Trace Strip trailing whitespace; avoid *"<>|? in path
Copy hangs, no alarm raised Source path points to a network share on a panel image Network share is unsupported on panel firmware Use SD card or USB stick as source
CRC mismatch after copy Media error on SD / USB Reformat SD card; replace USB stick Use a different physical media
Copy slower than expected Large directory tree, per-file overhead Measure with HMIRuntime.Trace timestamps Switch to archive-based deployment

Engineering Notes and Safety Considerations

  • Operator-initiated folder copies must not run during an active recipe load or write. The VBScript engine and the recipe subsystem share the file I/O subsystem; concurrent access produces file-lock errors that the procedure does not trap.
  • The recursive procedure calls MkDir and FileCopy through the runtime's COM layer. Errors are raised as runtime exceptions, not as COM errors, so use On Error Resume Next around each primitive if you need defensive behavior. The wrappers above already include On Error Resume Next around the MkDir in EnsureFolderExists; add the same guard around FileCopy if the destination media may be removed mid-copy.
  • Confirm the toolbox revision on the panel by reading \Storage Card\Siemens\HmiRTm\Tools\version.txt before commissioning a workaround. The support entry ID 106226404 lists every released revision.
  • If the project uses WinCC Runtime Professional on a PC, the toolbox File Explorer and the workaround procedure both work, but the PC runtime also exposes full Scripting.FileSystemObject. On PC runtime, replace the recursive CopyFolderRecursive with a direct call to FSO.CopyFolder; the runtime resolves the COM object without modification.
  • Folder-copy procedures cannot be cancelled mid-operation on a panel. If the deployment needs a cancel button, set a flag the procedure checks between FileCopy calls and abort cleanly on the next iteration.

Related Scripting Primitives Worth Knowing

Primitive Typical use in the workaround context
HMIRuntime.Trace Write a trace entry to the panel's diagnostic buffer for offline review
ShowSystemAlarm Surface a system alarm on the HMI for the operator
SmartTags("...") Read or write an HMI tag from script
HMIRuntime.FileSystem Access the runtime's filesystem helper on PC runtime
GetAttr + bit 16 Detect directory entries inside a Dir iteration

Frequently Asked Questions

Why does the Siemens HMI Toolbox File Explorer copy files but not folders?

The toolbox's internal copy wrapper calls FileSystemObject.CopyFile for every selected entry without branching on file type. When the entry is a directory, the call fails and the wrapper traps the error silently. The defect is in the wrapper, not in the panel's filesystem, which is why individual file copies succeed.

Can I use MoveFile to move a folder in a WinCC Comfort script?

No. MoveFile on WinCC Comfort / Advanced runtime is a single-file primitive. Calling it on a directory path fails silently in the same way the toolbox does. Use a recursive procedure that calls FileMove once per file and MkDir once per directory, or use the FSO.MoveFolder method on a PC runtime that exposes full FileSystemObject.

Which TIA Portal and toolbox version introduced the folder-copy defect?

The defect is present in the Toolbox for HMI Projects library shipped with every TIA Portal release from V14 SP1 through V20. The current support entry is ID 106226404. Verify the toolbox revision against the entry before deploying the workaround.

What paths should a folder-copy script use on a Comfort Panel?

Use canonical panel-side paths such as \Storage Card\Recipes\TTT\, \Storage Card2\Backup\, \usb\, and \usb2\. The runtime rejects absolute Windows paths and network shares on panel firmware. On PC runtime, \\server\share\ is allowed.

How do I deploy a directory tree to the panel when the toolbox cannot copy folders?

Package the directory as a single file on the engineering workstation and load it through the HMI files editor, which the TIA Portal documentation describes in Load files using the 'HMI files' editor. Then use a runtime helper script to unpack the file into the destination directory tree.

How many files can a recursive folder-copy script handle on a TP900 Comfort Panel?

The procedure scales linearly with the entry count. On a TP900 with a 200 MHz ARM and SD card media, a directory tree of 500 files completes in roughly 6 to 12 seconds. Above ~1000 entries or three levels of nesting, switch to the archive-based deployment approach to keep operator-visible latency under control.

Back to blog