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.
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:
- The wrapper iterates the source selection and calls
FileSystemObject.CopyFilefor 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. - 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 |
\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
- Compile the project in TIA Portal V16 (or matching version). Resolve every warning; the recursive procedure in particular must compile without missing-symbol errors.
- Download the project to the panel using the HMI files editor and the standard Download to device dialog.
- 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.
- From the operator screen, set
TagSrcFolderto the test folder andTagDstFolderto the destination, then press the Copy Folder button. - 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.
- 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.
- 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.
- 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.
- Repeat the test with the source folder containing a long path (32 characters or more) to confirm the runtime's path-length handling.
- 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
MkDirandFileCopythrough the runtime's COM layer. Errors are raised as runtime exceptions, not as COM errors, so useOn Error Resume Nextaround each primitive if you need defensive behavior. The wrappers above already includeOn Error Resume Nextaround theMkDirinEnsureFolderExists; add the same guard aroundFileCopyif the destination media may be removed mid-copy. - Confirm the toolbox revision on the panel by reading
\Storage Card\Siemens\HmiRTm\Tools\version.txtbefore 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 recursiveCopyFolderRecursivewith a direct call toFSO.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
FileCopycalls 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.