Resolving WinCC VBScript Project Path References Dynamically

David Krause13 min read
SiemensTutorial / How-toWinCC
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

The Hard-Coded Path Problem in WinCC VBScript

Most first-pass WinCC VBScript code embeds an absolute path such as C:\Program Files\Siemens\Automation\WinCC\WinCCProjects\MyPlant\Documents\recipe.xls directly into objExcelApp.Workbooks.Open or HMIRuntime.Tags.Write calls. The script works on the engineering station, passes FAT, then fails the first time the runtime PC is imaged, the project is renamed, the disk is re-lettered, or a parallel C: drive is mapped on the panel PC. The root cause is not WinCC; it is the absence of a project-relative anchor inside the script itself.

Three properties of a WinCC runtime project are stable regardless of where the project is installed:

  • The project's root folder (the directory that contains the project file, e.g. MyPlant.MCP or MyPlant.WCC).
  • Standard sub-folders under that root: GraCS (graphics/pictures), Library, Documents, Archive, ScriptLib, Logs.
  • The runtime object HMIRuntime, which is exposed to every C-/VBScript action.

A script only needs one of these anchors to compose a portable path. This article walks through the three production-grade methods used in WinCC V7, WinCC V7.4 SP1, WinCC Professional (TIA Portal V15–V18), and WinCC Runtime Advanced, and shows how to wrap each into a reusable helper function.

Win32 vs Win64 runtime: The VBScript engine inside WinCC is always 32-bit (cscript/wscript are not used; the WinCC C-Script and VBScript interpreter is a 32-bit host). Therefore the Excel object library must be the 32-bit Microsoft Excel XX.X Object Library, otherwise ActiveX component can't create object (Error 429) is raised the first time the script runs.

Prerequisites and Environment

Before adopting dynamic paths, confirm the runtime target meets the requirements below.

Component WinCC V7.4 / V7.5 WinCC Professional (TIA Portal) WinCC Runtime Advanced
VBScript interpreter Built-in, ANSI mode WinCC RT Professional: built-in; RT Advanced: VBScript via Global Script / local scripts Subset of VBScript (no FSO on some panels)
HMIRuntime object Yes (full) Yes (full in RT Pro, partial in RT Adv) Yes, RT Adv exposes HmiRuntime (note casing)
Scripting.FileSystemObject Yes (reference Microsoft Scripting Runtime) Yes in RT Pro; not guaranteed on every RT Adv panel image Conditional – test on target panel
Excel automation Requires 32-bit Excel or Microsoft Excel XX.X Object Library reference Same Not supported on most panels
Action trigger Picture event, tag trigger, scheduler Same Same

References used in this article:

Method 1 — HMIRuntime.ActiveProject.Path

The HMIRuntime automation object is the WinCC-supplied entry point for every C and VB action. Among its members, ActiveProject.Path returns the absolute directory of the currently loaded project — the directory that contains *.MCP (WinCC V7) or *.WCC (TIA Portal) — without a trailing backslash.

Syntax

HMIRuntime.ActiveProject.Path

Reference implementation

'\ ---------------------------------------------------------------
'\  Module:  mod_PathHelpers
'\  Purpose: Provide project-relative paths without hard-coding.
'\  Tested:  WinCC V7.4 SP1, WinCC V7.5 SP2, WinCC RT Professional V17
'\ ---------------------------------------------------------------

Function ProjectRoot()
    ProjectRoot = HMIRuntime.ActiveProject.Path
End Function

Function ProjectPath(ByVal relativeFolder, ByVal fileName)
    '\ Build a path such as <ProjectRoot>\Documents\recipe.xls
    Dim s
    s = HMIRuntime.ActiveProject.Path
    If Right(s, 1) <> "\" Then s = s & "\"
    ProjectPath = s & relativeFolder & "\" & fileName
End Function

'\ Example call inside a button-click action:
Dim strFile
strFile = ProjectPath("Documents", "recipe.xls")
MsgBox "Opening: " & vbCrLf & strFile
objExcelApp.Workbooks.Open strFile

Why this is the preferred anchor

  • Zero coupling to the calling picture, the calling script file, or any graphic PDL.
  • Stable across re-installations, drive reassignments, and project renaming.
  • Standard: documented in the WinCC VBScript reference (object HMIRuntime, property ActiveProject, sub-object Project, property Path).
Casing pitfall: TIA Portal WinCC Runtime Advanced exposes HmiRuntime (mixed case) rather than HMIRuntime. When porting code between WinCC V7 and RT Advanced, add a guard: If IsObject(HmiRuntime) Then ... ElseIf IsObject(HMIRuntime) Then ...

Method 2 — FileSystemObject Walk-Up from a Known File

There are situations where HMIRuntime.ActiveProject is not desirable — for example, when a script must run during project startup, before the runtime has fully bound ActiveProject, or inside a Global Script action that runs outside a picture context. The fall-back is to anchor the path to a file the script knows exists, then walk upward through FileSystemObject.ParentFolder.

The pattern, taken from the WinCC community and refined for production use:

Dim fso, f, s
Set fso = CreateObject("Scripting.FileSystemObject")
Set f   = fso.GetFile("An_Existing_Picture.PDL_") '\ replace with a real PDL on disk
s = UCase(f.Path)
s = UCase(f.ParentFolder.ParentFolder) & "\Documents\excelFile.xls"

MsgBox "Resolved to: " & s
objExcelApp.Workbooks.Open s

How the walk-up works

  1. GetFile("An_Existing_Picture.PDL_") resolves a known file relative to the WinCC working directory (typically GraCS\).
  2. f.Path returns the absolute path, e.g. C:\Program Files\Siemens\Automation\WinCC\WinCCProjects\MyPlant\GraCS\An_Existing_Picture.PDL_.
  3. f.ParentFolder is one level up — \GraCS.
  4. f.ParentFolder.ParentFolder is two levels up — the project root.
  5. The string "\Documents\excelFile.xls" is appended to land inside the conventional Documents sub-folder.

Hardening the FSO walk-up

Function ResolveSiblingPath(ByVal anchorFile, ByVal upLevels, ByVal tail)
    '\ anchorFile  : file relative to CWD that we are CERTAIN exists
    '\ upLevels    : how many ParentFolder hops to the project root
    '\ tail        : tail string beginning with "\", e.g. "\Documents\data.csv"
    Dim fso, f, p, i
    Set fso = CreateObject("Scripting.FileSystemObject")
    If Not fso.FileExists(anchorFile) Then
        Err.Raise vbObjectError + 1001, , "Anchor file not found: " & anchorFile
    End If
    Set f = fso.GetFile(anchorFile)
    p = f.ParentFolder.Path
    For i = 1 To upLevels
        Set p = fso.GetFolder(p).ParentFolder
    Next
    ResolveSiblingPath = p.Path & tail
End Function

'\ Usage:
Dim s
s = ResolveSiblingPath("An_Existing_Picture.PDL_", 2, "\Documents\recipe.xls")

Method 3 — Microsoft Scripting Runtime Walk-Up from the Script Itself

For global actions stored in ScriptLib\ rather than picture-bound actions, the script can walk up from its own location. The Microsoft Scripting team documents the pattern in the article How Can I Determine the Path to the Folder Where a Script is Running?. The native VBScript equivalent in WinCC is:

Function ScriptFolder()
    Dim fso, f
    Set fso = CreateObject("Scripting.FileSystemObject")
    '\ WScript.ScriptFullName is not available inside WinCC,
    '\ but the action is executed with CWD = ScriptLib (global)
    '\ or = GraCS (picture event). Use a known file as the anchor
    '\ instead of a non-existent WScript reference.
    Set f = fso.GetFile("StandardFunctions.bas_")  '\ any known file in CWD
    ScriptFolder = f.ParentFolder.Path
End Function

The general VBScript idiom using WScript.ScriptFullName does not work inside WinCC because WScript is not exposed. The Microsoft blog is still the canonical reference for the shape of the solution — substitute HMIRuntime or a known file for the WinCC equivalent.

Building a Portable Path Helper Module

In real projects, three or four file locations recur: Documents\, Archive\, Logs\, and a Templates\ folder for stamped-out Excel reports. Promote these into one module:

Option Explicit

Public Const FOLDER_DOCUMENTS  As String = "Documents"
Public Const FOLDER_LOGS       As String = "Logs"
Public Const FOLDER_TEMPLATES  As String = "Documents\Templates"

'\ Returns <ProjectRoot>
Public Function ProjectRoot() As String
    ProjectRoot = HMIRuntime.ActiveProject.Path
End Function

'\ Returns <ProjectRoot>\<subFolder>
Public Function ProjectFolder(ByVal subFolder As String) As String
    Dim p : p = ProjectRoot()
    If Right(p, 1) <> "\" Then p = p & "\"
    ProjectFolder = p & subFolder & "\"
End Function

'\ Returns <ProjectRoot>\<subFolder>\<fileName>
Public Function ProjectFile(ByVal subFolder As String, _
                            ByVal fileName As String) As String
    ProjectFile = ProjectFolder(subFolder) & fileName
End Function

Callers now read like configuration, not magic strings:

Dim wbPath
wbPath = ProjectFile(FOLDER_TEMPLATES, "RecipeTemplate.xltx")
objExcelApp.Workbooks.Open wbPath

Cross-Version Compatibility: WinCC V7 vs TIA Portal

The two runtime lines have identical concepts but slightly different object models. The table below is the minimum mapping required to port code unchanged.

Capability WinCC V7.4 / V7.5 WinCC RT Professional (TIA V15–V18)
Runtime object name HMIRuntime HmiRuntime (RT Pro) / HMIRuntime (legacy mode)
Project path property HMIRuntime.ActiveProject.Path HmiRuntime.ActiveProject.Path
Tag write HMIRuntime.Tags("MyTag").Write value HmiRuntime.Tags("MyTag").Write value
Trigger (cyclic) Configured on the action Configured on the action, name Trigger
Global script location <Project>\ScriptLib\ <Project>\ScriptLib\ for RT Pro; RT Adv uses project-local scripts only
FSO availability Always Always on RT Pro; absent on many RT Adv panel images
Office automation WinCC station must have 32-bit Office Same constraint; cannot host Office on RT Adv panels

A safe forward-compatible shim:

Function Rt()
    If IsObject(HmiRuntime) Then
        Set Rt = HmiRuntime
    ElseIf IsObject(HMIRuntime) Then
        Set Rt = HMIRuntime
    Else
        Err.Raise vbObjectError + 9001, , "Neither HMIRuntime nor HmiRuntime available"
    End If
End Function

Function ProjectRoot()
    ProjectRoot = Rt().ActiveProject.Path
End Function

Excel Workbook Integration Patterns

Dynamic paths only matter because the code that consumes them is fragile. Three patterns are common in production WinCC deployments.

Pattern A — Read a recipe from a project-shipped Excel template

Dim xlApp, xlWb, xlWs
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = False
xlApp.DisplayAlerts = False

Set xlWb = xlApp.Workbooks.Open(ProjectFile(FOLDER_TEMPLATES, "RecipeTemplate.xltx"))
Set xlWs = xlWb.Worksheets("Recipe")

Dim recipeID : recipeID = xlWs.Range("B2").Value
HMIRuntime.Tags("Recipe_ID").Write recipeID

xlWb.Close False
xlApp.Quit
Set xlWs = Nothing : Set xlWb = Nothing : Set xlApp = Nothing

Pattern B — Append a batch record to a project-local CSV

Sub AppendBatch(ByVal line)
    Dim fso, ts, path
    path = ProjectFile(FOLDER_LOGS, "BatchLog_" & Year(Now) & ".csv")
    Set fso = CreateObject("Scripting.FileSystemObject")
    If Not fso.FileExists(path) Then
        Set ts = fso.OpenTextFile(path, 2, True)   '\ ForWriting, create
        ts.WriteLine "Timestamp,BatchID,Operator,Result"
    Else
        Set ts = fso.OpenTextFile(path, 8, False)  '\ ForAppending
    End If
    ts.WriteLine FormatDateTime(Now, vbGeneralDate) & "," & line
    ts.Close
End Sub

Pattern C — Generate a stamped PDF from a template

Sub GenerateReportPDF(ByVal batchID As String)
    Dim xlApp, xlWb
    Set xlApp = CreateObject("Excel.Application")
    xlApp.Visible = False
    xlApp.DisplayAlerts = False

    Set xlWb = xlApp.Workbooks.Open(ProjectFile(FOLDER_TEMPLATES, "ReportTemplate.xltx"))
    xlWb.Worksheets("Sheet1").Range("B2").Value = batchID
    xlWb.ExportAsFixedFormat 0, ProjectFile(FOLDER_DOCUMENTS, "Batch_" & batchID & ".pdf")
    '\ 0 = xlTypePDF (Excel constant; the numeric avoids missing-reference errors)
    xlWb.Close False
    xlApp.Quit
End Sub
32-bit Office is mandatory. Even on a 64-bit Windows panel PC, WinCC's VBScript interpreter hosts Office automation in a 32-bit process. Installing 64-bit Office yields Automation error, The system cannot find the file specified (Error 80070002) on CreateObject("Excel.Application"). See Siemens KB 109746405.

Error Handling, Logging, and Diagnostics

A dynamic path that silently falls back to C:\ is worse than a hard-coded one. Wrap every external call in On Error Resume Next + an explicit check on Err.Number, and persist the error to a project-local log so the field engineer can recover without remote desktop.

Sub LogError(ByVal ctx As String, ByVal where As String)
    Dim fso, ts, path
    path = ProjectFile(FOLDER_LOGS, "ScriptErrors.log")
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts  = fso.OpenTextFile(path, 8, True)
    ts.WriteLine FormatDateTime(Now, vbGeneralDate) & vbTab & _
                 ctx & vbTab & where & vbTab & _
                 "Err.Number=" & Err.Number & vbTab & _
                 "Err.Description=" & Err.Description & vbTab & _
                 "Err.Source=" & Err.Source
    ts.Close
    On Error GoTo 0
End Sub

'\ Canonical call site:
Sub OpenRecipe()
    On Error Resume Next
    Dim path : path = ProjectFile(FOLDER_DOCUMENTS, "recipe.xls")
    If Err.Number <> 0 Then
        LogError "OpenRecipe", "ProjectFile"
        Exit Sub
    End If
    objExcelApp.Workbooks.Open path
    If Err.Number <> 0 Then
        LogError "OpenRecipe", "Workbooks.Open("" & path & "")"
        Exit Sub
    End If
    On Error GoTo 0
End Sub

Common error numbers observed in WinCC VBScript

Err.Number Meaning Likely cause Remediation
429 ActiveX component can't create object 64-bit Office installed, or Excel reference missing Install 32-bit Office; add Microsoft Excel XX.X Object Library reference
70 Permission denied File locked by another process, or UAC-protected path Close holders; run WinCC runtime as a user with write rights on Documents\
76 Path not found Sub-folder Documents missing on the target Have the script create the folder with fso.CreateFolder
80070002 The system cannot find the file specified 32/64-bit mismatch with Office, or template deleted Re-deploy the template via project download
80004005 Unspecified automation error Excel still showing modal dialog from prior call Set xlApp.DisplayAlerts = False; call xlApp.Quit; nullify objects

Verification and Deployment Checklist

Run this checklist on the panel PC before declaring the path fix complete.

  1. Open the WinCC project from a non-default location (e.g. D:\Projects\MyPlant\) and confirm HMIRuntime.ActiveProject.Path returns D:\Projects\MyPlant.
  2. Trigger the action that opens an Excel file. Verify the file opens and ScriptErrors.log remains empty.
  3. Move the entire project folder to a different drive letter (e.g. E:\) and re-start the WinCC runtime. The action must continue to work.
  4. Rename the project file (e.g. MyPlant.MCP → MyPlant_2024.MCP) and re-load. Verify the resolved path updates automatically.
  5. Force a permission failure: revoke write rights on Documents\ and confirm ScriptErrors.log records a 70 with the resolved path that was attempted.
  6. Stop the WinCC runtime, install 64-bit Office (test only), and confirm the action fails with Err 429 — proving the diagnostics are wired.
  7. Re-install 32-bit Office. Confirm recovery without restarting the WinCC runtime (the script re-creates the COM object on next invocation).
  8. Export the ScriptLib folder from the engineering station and diff it against the runtime copy to confirm parity.

Troubleshooting Matrix

Symptom Root cause Diagnostic Fix
Action fails only on the second runtime start Excel process leaked from the previous run; Quit not called Task Manager shows EXCEL.EXE *32 Always call xlApp.Quit and set object variables to Nothing
Path resolves but file does not open Template was deleted during a partial project download ScriptErrors.log shows Err 76 Add fso.CreateFolder and fso.CopyFile from a known-good source at startup
Path resolves to C:\Program Files\Siemens\... on a panel without that drive Script is using a hard-coded fallback Grep the source for C:\Program Files Remove all literal absolute paths; route every path through ProjectFile()
Works in WinCC V7, fails in RT Professional Object name case mismatch Runtime debugger shows Object required: 'HMIRuntime' Use the Rt() shim shown earlier
Works on engineering station, fails on panel Panel image lacks FSO Err 429 on CreateObject("Scripting.FileSystemObject") Use only HMIRuntime-based paths on RT Advanced; pre-create folders on the engineering station and download them
Path with spaces fails to open in Excel Spaces not properly handled when command-line tooling is invoked Cmd-line opens fine; Excel call fails Wrap path in Chr(34) only when needed; Excel Workbooks.Open handles spaces natively

Field-Proven Caveats

  • Network shares. HMIRuntime.ActiveProject.Path works with UNC paths (\\srv\WinCC\MyPlant) provided the WinCC service account has read/write rights on the share. Do not mix UNC and mapped-drive paths within the same project.
  • Project duplication. When a project is duplicated for a sister line, search for any remaining C:\Program Files\Siemens\... literals — those are the next failure candidates.
  • Folder creation race. If a cyclic action and a startup action both try to create Logs\ at the same time, wrap the call in On Error Resume Next; the second caller will see Err 76/Path already exists and silently continue.
  • Logging into the same file. Always null ts after Close; leaving the TextStream open across the runtime boundary leaks handles.
  • Localization. Windows localized Documents folders do not affect WinCC — the Documents sub-folder is created under the WinCC project, not under the user profile, so locale does not matter.

FAQ

Does HMIRuntime.ActiveProject.Path include a trailing backslash?

No. HMIRuntime.ActiveProject.Path returns the directory without a trailing separator. Always append "\" (or use ProjectFolder() from the helper module above) before concatenating sub-folders or file names.

Why does my VBScript work in the WinCC Explorer but fail at runtime?

Most runtime-only failures are caused by missing reference resolution. In the engineering station, the script runs with full IDE-time references; at runtime, only the registered type libraries resolve. Ensure Microsoft Scripting Runtime and Microsoft Excel XX.X Object Library are registered system-wide (32-bit), and avoid New keyword syntax — use CreateObject("Excel.Application") instead.

Can I use the same dynamic-path code on WinCC Runtime Advanced on a Comfort Panel?

Only partially. HmiRuntime.ActiveProject.Path is available, but FileSystemObject is not guaranteed on all RT Adv images and Excel automation is not supported. Stick to ProjectFolder() for read/write of tag archives and CSV files; never attempt CreateObject("Excel.Application") on a panel.

How do I find the project path from inside a global action that runs before picture activation?

Use HMIRuntime.ActiveProject.Path directly — it is independent of any picture. If ActiveProject is not yet bound (very early in startup), fall back to the FileSystemObject walk-up method anchored on a known file in the ScriptLib folder.

Is there a way to keep the Excel reference out of the project but still drive Excel?

Yes. Use late binding: CreateObject("Excel.Application") and dispatch through Invoke-style property names. The downside is no IntelliSense and no compile-time checking; the upside is zero references and immunity to Office version bumps. For new projects, prefer late binding plus the Path helpers above.

Back to blog