Overview
WinCC Unified scripting on Unified Comfort Panels and on PC Runtime gives the operator an I/O field that can collect a folder or file name, but the runtime has no built-in IsValidWindowsFileName function. The system is fully responsible for enforcing the Windows naming rules: a bad character in the name, a reserved device name, a trailing period, or a path longer than 260 characters will either be rejected silently by the operating system or, worse, create a file the operator cannot address. This reference documents a defensive VBScript validator, a try/catch pattern around the FileSystemObject, an equivalent JavaScript implementation, the path-length constraints, and the step-by-step wiring on a Unified screen.
Two strategies are valid and usually combined. The first runs on the operator's keystroke and gives immediate feedback, so the operator fixes the entry before pressing Save. The second wraps the actual filesystem call and catches anything the validator missed, including network-share errors and case collisions on SMB mounts.
Prerequisites
- TIA Portal V17 Update 4 or later; TIA Portal V18 for new projects.
- WinCC Unified V17 or V18 engineering and runtime installed.
- Unified Comfort Panel: MTP700, MTP1000, MTP1200, MTP1500, MTP1900, MTP2200 with image V17.0.0.18 or later, or PC Runtime V17/V18.
- JavaScript engine on the runtime requires image V16.4 or later (VBS is available from V16.0).
- Scripting licensed on the HMI device. The WinCC Unified Scripting license is part of the standard runtime license; confirm under Runtime Settings > Services > Scripting.
- A project tag of type
WStringbound to the I/O field that collects the name.
Windows File and Folder Naming Rules
The validator must enforce the same rules that the Windows file system enforces. The authoritative source is the Microsoft Naming Files, Paths, and Namespaces article, which lists every reserved character and every reserved device name. The constraints the VBS function below covers are summarized here:
| Rule | Detail |
|---|---|
| Reserved characters |
< > : " / \ | ? * plus control characters 0x00 through 0x1F |
| Reserved device names |
CON, PRN, AUX, NUL, COM1 through COM9, LPT1 through LPT9, with or without an extension |
| Trailing characters | No trailing space and no trailing period on the final component |
| Length | Each name component ≤ 255 characters; full path ≤ 260 characters unless long paths are enabled |
| Empty input | Empty string is invalid; whitespace-only is invalid |
| Reserved-only names | A name that consists entirely of dots (e.g. .., ...) is invalid |
Script Placement and Architecture
Bind the validator to one of three locations, ordered by how early you want to reject the input:
- On the I/O field "Changed" event: rejects the value and shows an inline message. Best for guiding the operator live.
- On a button "Click" event: rejects the value when the operator presses Save or Create. Best for forms that need the full string for one validation pass.
- On a custom function in the project scripts: a shared function that both event handlers call, so the rules exist in one place.
Create a project-wide VBScript module called FileNameValidation under Scripts > VBScripts in the TIA Portal project tree. Add a function IsValidWinName and a function TryCreateFolder. Reference both from the screen events that accept a name.
VBScript Validation Function
Paste the function below into the FileNameValidation module. The function returns True for a valid name and False for an invalid one, with a human-readable reason written to the second argument.
' Returns True if sValue is a valid Windows file or folder name component.
' sReason is populated on failure.
Function IsValidWinName(ByVal sValue, ByRef sReason)
Dim i, j, sChar, sName, sBase, bOnlyDots
Dim arrReserved
sReason = ""
sName = Trim(sValue)
If Len(sName) = 0 Then
sReason = "Name is empty."
IsValidWinName = False
Exit Function
End If
If Len(sName) > 255 Then
sReason = "Name exceeds 255 characters."
IsValidWinName = False
Exit Function
End If
If Right(sName, 1) = " " Or Right(sName, 1) = "." Then
sReason = "Name must not end with space or period."
IsValidWinName = False
Exit Function
End If
' Reserved device names, with or without extension.
If InStr(sName, ".") > 0 Then
sBase = UCase(Left(sName, InStr(sName, ".") - 1))
Else
sBase = UCase(sName)
End If
arrReserved = Array("CON","PRN","AUX","NUL", _
"COM1","COM2","COM3","COM4","COM5", _
"COM6","COM7","COM8","COM9", _
"LPT1","LPT2","LPT3","LPT4","LPT5", _
"LPT6","LPT7","LPT8","LPT9")
For i = 0 To UBound(arrReserved)
If sBase = arrReserved(i) Then
sReason = "Name is a reserved device name (" & sBase & ")."
IsValidWinName = False
Exit Function
End If
Next
' Reserved characters and control characters.
For i = 1 To Len(sName)
sChar = Mid(sName, i, 1)
Select Case sChar
Case "<", ">", ":", """", "/", "\", "|", "?", "*"
sReason = "Name contains reserved character '" & sChar & "'."
IsValidWinName = False
Exit Function
End Select
If Asc(sChar) < 32 Then
sReason = "Name contains a control character."
IsValidWinName = False
Exit Function
End If
Next
' Name consisting only of dots.
bOnlyDots = True
For j = 1 To Len(sName)
If Mid(sName, j, 1) <> "." Then
bOnlyDots = False
Exit For
End If
Next
If bOnlyDots Then
sReason = "Name must not consist only of dots."
IsValidWinName = False
Exit Function
End If
IsValidWinName = True
End Function
Call the function from an I/O field's "Changed" event so the operator sees the failure reason as they type:
Dim sReason, bOK
bOK = IsValidWinName(SmartTag("FolderName"), sReason)
If Not bOK Then
ShowSystemAlarm("Invalid name: " & sReason)
Else
ShowSystemAlarm("Name is valid.")
End If
Try-Catch Validation with FileSystemObject
The validator above does not check that the path is reachable, that the share is online, or that the runtime user has write permission. Wrap the actual write in a try/catch-equivalent that uses the VBScript Err object. WinCC Unified exposes the FileSystemObject through CreateObject on both Unified Comfort Panels and PC Runtime.
Function TryCreateFolder(ByVal sFullPath, ByRef sErrMsg)
Dim oFSO
On Error Resume Next
Set oFSO = CreateObject("Scripting.FileSystemObject")
If Err.Number <> 0 Then
sErrMsg = "FSO unavailable: 0x" & Hex(Err.Number)
TryCreateFolder = False
Exit Function
End If
If oFSO.FolderExists(sFullPath) Then
sErrMsg = "Folder already exists."
TryCreateFolder = False
Exit Function
End If
oFSO.CreateFolder sFullPath
If Err.Number <> 0 Then
sErrMsg = "CreateFolder failed: 0x" & Hex(Err.Number) & " " & Err.Description
TryCreateFolder = False
Else
sErrMsg = ""
TryCreateFolder = True
End If
On Error Goto 0
End Function
Err object is the only error signal. Always set On Error Goto 0 after the FSO call so unrelated runtime errors are not silently suppressed.Common HRESULT values returned through Err.Number from the FileSystemObject:
| Hex | Decimal | Meaning |
|---|---|---|
| 0x800A0046 | 32774 | Permission denied |
| 0x800A0035 | 52 | File not found |
| 0x800A0034 | 52 | File already exists |
| 0x800A004C | 76 | Path not found |
JavaScript RegExp Implementation
The VBS engine on WinCC Unified does not expose the Windows Script Host VBScript.RegExp object by default, so the function above uses InStr, Mid, and a Select Case scan. If your faceplates already use JavaScript, the RegExp object is built into the JavaScript engine and the equivalent validator is shorter:
// Project script, exported as IsValidWinName(sValue)
export function IsValidWinName(sValue) {
if (typeof sValue !== 'string') return { ok: false, reason: 'Not a string' };
const reserved = /^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\..*)?$/i;
const badChar = /[<>:"\/\\|?*\x00-\x1F]/;
const name = sValue.trim();
if (name.length === 0) return { ok: false, reason: 'Empty' };
if (name.length > 255) return { ok: false, reason: 'Longer than 255 characters' };
if (/^[. ]+$/.test(name)) return { ok: false, reason: 'Only dots or spaces' };
if (/[. ]$/.test(name)) return { ok: false, reason: 'Trailing space or period' };
if (badChar.test(name)) return { ok: false, reason: 'Reserved character' };
if (reserved.test(name)) return { ok: false, reason: 'Reserved device name' };
return { ok: true, reason: '' };
}
Call the JavaScript function from a script module bound to a screen event, the same way the VBS function is called. Return the reason string to the operator through a String tag bound to an output field, or raise a system alarm with HMIRuntime.Alarm from the JavaScript context.
\ and /, run the component check on each segment, and verify the root segment matches ^[A-Z]:$ or starts with \\\\ for a UNC path.Path Length, Long Paths, and Case-Sensitive Shares
The Win32 API uses MAX_PATH = 260 characters by default. The Unified scripting engine calls the same Win32 APIs, so a full path longer than 260 characters returns error 0x800A004C (path not found) even when every name component is valid. Long path support is enabled through the registry on the runtime image:
- Open the registry on the runtime PC or panel image:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem. - Set
LongPathsEnabled(DWORD) to1. - Reboot the runtime.
On Unified Comfort Panels, the registry can be reached through the Siemens Image Configuration tool. The Microsoft Maximum Path Length Limitation article documents the LongPathsEnabled key. Validate the full path length in the script before the call to fail fast:
If Len(sFullPath) > 260 Then
sReason = "Path exceeds 260 characters; long paths are not enabled on this runtime."
End If
Windows is case-insensitive by default, but a Unified panel that exports to a Linux SMB share hits a case-sensitive file system. The Windows rules above do not check for case collisions. Add an explicit existence check before the write:
Function IsNameFree(ByVal sDir, ByVal sName)
Dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")
Dim sPath : sPath = oFSO.BuildPath(sDir, sName)
IsNameFree = Not (oFSO.FileExists(sPath) Or oFSO.FolderExists(sPath))
End Function
Step-by-Step Implementation
- Open the TIA Portal project, select the HMI device, and add a new VBScript module under Scripts > VBScripts called
FileNameValidation. - Paste the
IsValidWinNameandTryCreateFolderfunctions from the sections above into the module. - Compile the project (Project > Compile > Software (rebuild all)) to confirm there are no syntax errors. The output window lists each module and the number of errors; expect zero.
- Open the screen that hosts the name entry I/O field. Add a "Changed" event on the I/O field and call
IsValidWinNameagainst the tag that holds the entry. - On the same screen, add an output field bound to a string tag. In the same Changed event, write the failure reason into that tag so the operator sees the explanation live.
- Add a button labeled "Create folder" with a "Click" event. In the Click handler, call
IsValidWinNamefirst, then callTryCreateFolderonly when validation passes. Show the FSO error message in the output field when the call fails. - Compile and download to the Unified Comfort Panel or PC Runtime.
- Open the runtime and intentionally enter the test cases from the verification checklist below. Each must be rejected with the matching reason.
- Enter a clean name (e.g.
Reports_2025). The validator returns True and the folder is created on the share.
Verification and Troubleshooting
Run the following matrix on the deployed runtime before sign-off. The first block is a positive and negative verification table; the second is a troubleshooting matrix.
| Input | Expected | Reason returned |
|---|---|---|
CON |
Reject | Reserved device name (CON) |
CON.txt |
Reject | Reserved device name (CON) |
a/b |
Reject | Reserved character '/' |
foo:bar |
Reject | Reserved character ':' |
foo?bar |
Reject | Reserved character '?' |
| 256 characters | Reject | Exceeds 255 characters |
(two spaces) |
Reject | Name is empty |
... |
Reject | Must not consist only of dots |
foo (trailing space) |
Reject | Trailing space or period |
Reports_2025 |
Accept | (empty) |
| Symptom | Likely cause | Fix |
|---|---|---|
| Validator returns True but CreateFolder fails | Path segment after the typed name contains a reserved character, e.g. an absolute path was typed in | Split the full path on \ and validate every segment |
| Validator returns False for a name that looks clean | Trailing space from the I/O field property is preserved | Trim the input in the validator (already in the snippet) and also clear the I/O field's "Clear on invalid" property |
| FSO returns 0x800A004C on a short path | Long path disabled and the absolute path includes a long network share prefix | Enable LongPathsEnabled on the runtime image, or move the share closer to the root |
JavaScript IsValidWinName is not found |
Function not exported or panel is on image V16.0-V16.3 without the JavaScript engine | Update panel image to V16.4 or later; verify the function is exported with export function
|
| Validator passes but file is created in wrong case on SMB share | Case-sensitive share | Add the IsNameFree check or normalize case before write |
| Script does not fire on the I/O field | Runtime setting "Scripting" disabled or scripting not licensed | Enable scripting under Runtime Settings > Services; confirm the HMI license includes the Unified Scripting component |
| Operator can paste a control character | I/O field "Input check" set to "None" | Set "Input check" to "Alphanumeric" or write a JavaScript onkeydown handler on the faceplate to drop control characters |
Edge Cases and Performance
Edge cases that the simple validator handles correctly but that the operator should be aware of:
- Unicode in folder names: Windows allows Unicode in file names, including characters from extended code pages. The validator above does not block Unicode, which is correct. If the share does not support Unicode (legacy FAT), reject code points above U+007F at the panel level.
-
Names with leading periods:
.gitignoreis valid on Windows. The validator allows it. On a Linux share, a leading dot hides the file, which may or may not be the desired behavior. Document this for the operator. -
Numeric-only names:
12345is valid. Do not add a "must contain a letter" rule unless the project requires it. - Embedded null characters: blocked by the control character check (0x00-0x1F). The I/O field on Unified usually blocks these at input, but a paste from the clipboard can sneak them in.
The VBScript scan is O(n) over the name length, which is bounded at 255. Typical execution is well under 1 ms on a Unified Comfort Panel. Call the validator on the Changed event of the I/O field, not on every screen cycle. The try/catch with FileSystemObject.CreateFolder adds a filesystem roundtrip and a network roundtrip on remote shares; call it once on the Save event, not on every keystroke.
FAQ
Can I use a regular expression in WinCC Unified VBScript?
The VBS engine on WinCC Unified does not expose the Windows Script Host RegExp object by default; you cannot reliably call CreateObject("VBScript.RegExp") from runtime scripts. Use a string scan with InStr, Mid, and Select Case instead, or switch to the JavaScript engine where the RegExp object is built into the language.
Which characters are reserved in a Windows file name?
The reserved set is < > : " / \ | ? * plus control characters 0x00-0x1F. A name may not end with a space or period, may not be empty, and may not be a reserved device name such as CON, PRN, AUX, NUL, COM1 through COM9, or LPT1 through LPT9. The full list is in the Microsoft Naming Files, Paths, and Namespaces article.
Should I validate before the call or use a try-catch on the file system call?
Both. Run the inline validator on the Changed event of the I/O field to give immediate feedback. Run FileSystemObject.CreateFolder wrapped in On Error Resume Next on the Save event so any path or permission error on the share is surfaced with a clear message.
Why does my validator pass but the file system call still fail with "path not found"?
The name component is valid but the full path exceeds 260 characters and the runtime image has long path support disabled. Enable LongPathsEnabled in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem, shorten the share prefix, or check the full path length in the script before the call.
Is FileSystemObject available on a Unified Comfort Panel?
Yes. CreateObject("Scripting.FileSystemObject") is available on Unified Comfort Panels running image V16 or later and on PC Runtime V16 or later. Permission to write the target directory is governed by the runtime user, not the script; configure the share or local folder ACL with the runtime's service account in mind.