WinCC V16 VBScript Stops Executing: Root Cause and Field Fix

David Krause12 min read
SiemensTroubleshootingWinCC
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

On TIA Portal V16 / WinCC Runtime Advanced V16 panels and PC-based HMIs, a project that runs cleanly for 24-72 hours suddenly stops executing any VBScript. Events that are configured to call Sub Procedure_xxx() blocks no longer fire. The HMI itself continues to respond, tags still update, screens still load, and the connection to the PLC remains healthy. Only the script layer is dead. A restart of the WinCC Runtime recovers operation for one to two minutes, after which scripts stop firing again. A full reboot of the PC restores the system for another 24-72 hours before the failure repeats.

This pattern is a classic object lifecycle / runtime resource exhaustion in the VBScript engine that WinCC Advanced hosts. It is not a PLC, network, or HMI tag problem. The most common trigger is a script that creates COM/ActiveX objects via CreateObject or GetObject without releasing the reference, and it is amplified by long runtime sessions and the absence of a cumulative TIA Portal V16 update package.

Affected Versions and Components

Component Affected Versions Notes
TIA Portal V16 (all service packs prior to V16 Update 5) VBScript runtime issues are heavily reduced in V17/V18
WinCC Advanced (ES) V16.0 + SP1 through V16 Update 4 Engineering tool version that compiled the project
WinCC Runtime Advanced V16.0.0.0 - V16.0.4.0 RT DLLs in C:\Program Files\Siemens\Automation\WinCC RT Advanced
Windows Windows 10 LTSC 2019, Windows Server 2016/2019 VBScript 5.812 (msvbvm60.dll) is shipped as an OS feature
VBScript engine Microsoft Windows Script Host 5.812 Subject to Microsoft deprecation roadmap

Projects that have been migrated forward from V15.1 to V16 are particularly exposed because they may still contain legacy script patterns that worked on the older VBScript 5.806 runtime.

Root Cause: Unreleased COM Object References

Every CreateObject("WScript.Shell"), CreateObject("ADODB.Recordset"), CreateObject("Scripting.FileSystemObject"), or CreateObject("Excel.Application") call inside a WinCC VBScript allocates a COM object on the WinCC RT process heap. WinCC does not release these objects when the script Sub exits. VBScript 5.812 has no deterministic garbage collector - it uses a reference-counting strategy that only frees the object when its count drops to zero. If the script stores the object in a global variable, or never sets the variable to Nothing at the end of the Sub, the reference is held for the entire runtime session.

Multiply one leaked object per call by a script that is called on every tag change, on every alarm, or on a 1-second cycle, and the RT process can leak hundreds of COM objects per hour. After roughly 10,000-30,000 unreleased objects (the limit varies by object type and Windows heap tuning), the VBScript engine refuses to instantiate new objects. New scripts silently fail to run. Existing event-driven calls return without executing the body. This is exactly the symptom described: scripts ran fine for two days, then stopped, restart recovered for two minutes (until the next script call), reboot recovered for two days (until the leak count rebuilt).

Secondary Root Cause: Out-of-Date V16 Update

Siemens released four cumulative update packages for TIA Portal V16 between January 2020 and January 2021. Update 5 in particular contains fixes to the WinCC RT script scheduler and to memory handling in the graphics runtime. If the engineering station and the runtime target are not on the same update level, or if the runtime is on the original V16.0.0.0 RT DLLs, the script engine can exhibit the exact hang described above even when the source code is clean.

Check the installed version before changing any source code. A five-minute version check can save a day of script refactoring.

Diagnostic Procedure

Step 1: Identify the WinCC RT version

  1. On the runtime PC, open C:\Program Files\Siemens\Automation\WinCC RT Advanced\bin\RTLicenseInfo.exe or look at HKLM\SOFTWARE\Siemens\Automation\WinCC RT Advanced\CurrentVersion.
  2. Note the build number. Examples: 16.0.0.0 (original), 16.0.1.0 (Update 1), 16.0.5.0 (Update 5).
  3. Compare against the latest available V16 update in the Siemens Industry Online Support portal (entry ID 109769202).

Step 2: Capture the WinCC diagnostic trace

  1. Open WinCC Runtime Advanced Loader on the runtime PC.
  2. Click Settings, navigate to Diagnostics.
  3. Enable Trace file and set the path to D:\Logs\WinCC_RT_Trace.log.
  4. Set the verbosity to Extended (this includes script engine messages).
  5. Restart the runtime and let it run until the failure recurs.

Open the trace file. Search for the following markers:

Marker in trace Meaning Action
CScriptEngine::Execute: OutOfMemory COM heap exhausted - confirms leak Apply Step 3 fix to all scripts
CScriptEngine::Execute: script timeout Script exceeded configured timeout (default 10s) Move work off the event handler
VBScript runtime error 0x800A01A8 Mandatory object missing - reference not released Check object cleanup
VBScript runtime error 0x800A0005 Invalid procedure call or argument Check data types in HMIRuntime.Tags
VBScript runtime error 0x800A01B6 Object doesn't support this property/method Wrapper object was not created
CScriptEngine::Dispatch: 0x80020101 Call rejected by server (engine wedged) Engine hang - update required

Step 3: Detect the offending script

  1. Open TIA Portal, open the project, right-click the HMI device, choose Compile > Software (rebuild all).
  2. Enable Project > Compiler output > Script overview. This produces a list of every script file, its calling event, and its cycle time estimate.
  3. Sort the list by the event cycle and identify any script bound to a sub-second cycle or to a tag change with no debounce.
  4. For every such script, open the source and search for CreateObject, GetObject, and New on COM types (e.g. New ADODB.Recordset).

Step 4: Check the Windows event log

WinCC does not write VBScript exceptions to the Windows Application event log by default. To capture them:

  1. In the WinCC RT Loader, Settings > Alarms > System messages, enable Log system messages and Display system messages.
  2. Filter on alarm class System, event ID 1000-1099, and look for the text pattern Script.

For deep diagnostics, also enable Process Monitor (ProcMon) from Sysinternals with a filter on the process CCRtAgent.exe and the operation Load Image - a failing CreateObject shows up as a failed Load Image of the target DLL (e.g. scrrun.dll for FileSystemObject).

Solution 1: Explicit Object Cleanup in Every Script

Apply the following template to every VBScript in the project, not only the ones that crash. The fix is mechanical and reversible, and Siemens official WinCC V16 scripting guidelines explicitly call out object lifetime management.

Template: object cleanup pattern

Sub DoReadLogFile()
    Dim oFSO, oFile, oTextStream
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.GetFile("D:\Logs\recipe.log")
    Set oTextStream = oFile.OpenAsTextStream(1, -2)

    ' ... body that uses oTextStream ...

    ' RELEASE ORDER MATTERS - release child first, then parent
    oTextStream.Close
    Set oTextStream = Nothing
    Set oFile = Nothing
    Set oFSO = Nothing
End Sub

Anti-pattern (causes the leak):

Sub DoReadLogFile()
    Dim oFSO
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Dim oFile
    Set oFile = oFSO.GetFile("D:\Logs\recipe.log")
    ' ... no .Close, no Set ... = Nothing ...
End Sub

Cleanup rules

  • Always close streams and recordsets with their .Close method before setting the object to Nothing.
  • Release in reverse order of creation: child objects first, parent last.
  • If a function returns an object, document which caller owns the reference and who releases it.
  • For Excel automation (CreateObject("Excel.Application")), call .Quit on the application object, then set Set xlApp = Nothing. Excel is the most common single culprit because each call spawns a full process.
  • Avoid Set of COM objects into module-level (global) variables. If you must, release them in a dedicated shutdown Sub bound to the On Deactivate HMI event.

Solution 2: Update to the Latest V16 Cumulative Package

  1. Download the latest TIA Portal V16 update from the Siemens support portal entry 109769202 - TIA Portal V16 Update.
  2. Install the update on the engineering station first. Recompile the project (full rebuild, not incremental).
  3. Install the matching WinCC Runtime Advanced V16 Update on the runtime target. The RT update is shipped as a separate download, identified by the same entry ID plus the suffix _RT.
  4. Reboot the runtime PC and confirm the RT DLL version changed via the registry key in Step 1 of diagnostics.
The TIA Portal ES update alone does not update the runtime DLLs. The runtime target must be patched independently. A common field error is to patch the engineering PC, recompile, deploy, and assume the runtime is updated. It is not.

Solution 3: Refactor Sub-Second Event-Bound Scripts

Scripts bound to a tag change on a fast-changing tag (e.g. a position encoder updating every 10 ms) are a hidden source of object churn. Each event instance is a fresh script execution context, and any global state survives across instances. Two improvements:

  1. Add a debounce guard at the top of the Sub: only execute the body if a configured interval has elapsed since the last run, using Now() comparison or the internal HMIRuntime.System.Timer.
  2. Move long-running work to a separate cyclic script triggered on a 500 ms-1000 ms base, and only signal the event to the HMI via a boolean tag.
' Debounce pattern
Const INTERVAL_MS = 1000
Dim tLast
If tLast = 0 Then tLast = 0
If (Timer - tLast) * 1000 < INTERVAL_MS Then Exit Sub
tLast = Timer

Solution 4: Add a Watchdog Script and Memory Trace

Add a single, low-frequency watchdog script that runs every 60 s on a tag-change event driven by an internal clock tag. The watchdog logs the working set of the WinCC RT process and the number of currently active COM objects. This gives early warning before the next failure.

Sub LogMemory()
    Dim oWMI, oProcess, oProcesses
    Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
    Set oProcesses = oWMI.ExecQuery("Select * From Win32_Process Where Name='CCRtAgent.exe'")
    For Each oProcess In oProcesses
        HMIRuntime.Trace "Mem " & Now() & " WS=" & _
            oProcess.WorkingSetSize & " Hnd=" & oProcess.HandleCount & vbCrLf
    Next
    Set oProcesses = Nothing
    Set oWMI = Nothing
End Sub

The HMIRuntime.Trace call writes to the same trace file enabled in Step 2 of diagnostics. A steadily rising working set over a 24-hour period is direct evidence of a leak; a flat line after applying Solution 1 confirms the fix.

Verification

  1. After applying the cleanup pattern and the update, restart the runtime and let it run for at least 72 hours, ideally through a weekend.
  2. Confirm no OutOfMemory entries appear in the WinCC trace file.
  3. Confirm the CCRtAgent.exe working set remains within +/- 15 percent of the value at hour 1, measured at the same time of day.
  4. Confirm the HMI alarm log shows zero System-class events with the text Script during the verification window.
  5. Trigger each previously failing event manually from the engineering station (e.g. simulate a recipe load, a language change, a tag change) and verify the script body executes by checking the trace file for the expected Trace line.

Long-Term Mitigation: Prepare for VBScript Retirement

Microsoft has formally announced that VBScript is being retired from future versions of Windows. The VBScript runtime DLLs (vbscript.dll, msvbvm60.dll, scrrun.dll, scrobj.dll) will be removed from the Windows image. Existing scripts will continue to run on Windows 10 LTSC 2019 and Windows 11 22H2 as long as the optional VBScript feature is installed, but on any new Windows release shipped after retirement, every WinCC V16 VBScript will fail to execute. The exact timeline is published in the Microsoft Windows IT Pro Blog entry on VBScript deprecation.

For WinCC, the path forward is:

  • Plan a migration of all event-driven logic from VBScript to C# (WinCC Unified), to C-VBScript within WinCC Professional, or to the function library of a newer TIA Portal version (V17, V18, V19).
  • For new projects on TIA Portal V18 and later, prefer WinCC Unified with the modern C# scripting environment. VBScript is no longer the primary automation language.
  • Lock the runtime PC to a Windows build that still ships VBScript for the lifetime of the WinCC V16 installation. This is a temporary measure; do not build new production lines on it.

Troubleshooting Matrix

Symptom First Check Likely Cause Fix
Scripts stop after 24-72 h, restart helps for 1-2 min Search for CreateObject in project COM leak Apply Solution 1 (cleanup) + Solution 2 (update)
Scripts stop immediately after deploy Check event trigger in HMI tags Missing trigger tag or wrong event type Re-bind event to the intended tag
Specific script only fails, others run Read trace line for the failing script ID Data type mismatch or null reference Add IsNull / IsEmpty guards
Scripts run slowly, eventually time out Check working set of CCRtAgent.exe Memory pressure from external app (Excel) Switch to CSV/TSV instead of Excel automation
Failure only on language change Inspect OnLanguageChange event Global object created per language Release objects in the language-change handler
Failure coincides with antivirus scan Check CCRtAgent.exe load time in ProcMon AV locking vbscript.dll Add WinCC RT folder to AV exclusions

Checklist Before Calling Siemens Support

  1. Exact TIA Portal version (with update level) on ES.
  2. Exact WinCC RT version (with update level) on runtime target.
  3. Exact Windows version and build number.
  4. WinCC trace file from a session that contained the failure, in extended verbosity.
  5. Output of the watchdog script in Solution 4 covering the 24 hours before the failure.
  6. List of every CreateObject / New call in the project, with the file name and the calling event.
  7. Output of CCRtAgent.exe working set, sampled every 5 minutes for the last 24 hours (Task Manager Details tab, right-click > Save selection).

FAQ

Why do my WinCC V16 VBScripts stop executing after one or two days but the rest of the HMI works fine?

The VBScript engine inside the WinCC RT process runs out of usable COM objects because scripts created objects with CreateObject or GetObject and never released them. The first symptom is that newly scheduled scripts silently fail to fire, exactly as described in the source report. The two-day cycle matches the typical time to leak 10,000-30,000 objects at the script cadence of a medium-sized project.

Where are WinCC Runtime Advanced log files located in V16?

Trace files are written to the path configured in the WinCC RT Loader under Settings > Diagnostics. The default path is C:\ProgramData\Siemens\Automation\Logfiles\WinCC RT Advanced. The Application event log only contains system-level entries, not VBScript exceptions, unless you enable Log system messages in the alarm configuration of the WinCC project.

Does updating TIA Portal V16 also update the WinCC Runtime?

No. TIA Portal V16 updates and WinCC Runtime Advanced V16 updates are distributed as separate downloads. The engineering station is updated by the TIA Portal installer; the runtime target must be updated by the matching WinCC RT Advanced installer. A common field error is to update only the ES, redeploy, and assume the runtime is patched.

Will VBScript still work in future versions of Windows for my WinCC V16 project?

Microsoft has formally retired VBScript and will remove the VBScript DLLs from future Windows releases. Existing WinCC V16 projects will keep working on Windows 10 LTSC 2019 and Windows 11 22H2 as long as the optional VBScript feature is installed, but any new Windows release after retirement will not host VBScript at all. Plan a migration to WinCC Unified (C#) or to a newer TIA Portal version for any new project.

How do I find which script is leaking objects without adding tracing code?

Enable the WinCC RT extended trace, set the verbosity to Extended, and let the system run until the failure recurs. Search the trace for OutOfMemory, 0x800A01A8, and 0x80020101. Each entry contains the script ID and the calling event. Cross-reference the script ID with the Script overview generated by the TIA Portal compiler to identify the exact file and Sub responsible.

Back to blog