Reading the WinCC Project Version at Runtime with C and VBS Scripts
Every Siemens WinCC V7.x project carries a version identifier in its Configuration Studio (CS) metadata, but that value is normally only visible in WinCC Explorer, not in runtime. Engineers frequently need to expose the running project version to the HMI faceplate, the alarm log, an audit trail, or a conditional graphics script so that maintenance staff can immediately confirm which revision of the project is loaded on a station or a server. This reference documents the supported way to read MCPTPROJECT.PROJECTVERSION from runtime using a WinCC C-script, the alternative routes using VBS and WinCC internal tags, and the commissioning steps to wire the result into a faceplate or archive.
1. Prerequisites
- WinCC V7.0 SP3 or later, running on Windows 7 SP1 / Windows Server 2008 R2 or newer.
- Local administrator rights on the engineering station to configure the project version in the project properties dialog.
- The WinCC project must be opened at least once in WinCC Explorer so that the CS database is created and the DSN is registered.
- Global Scripting rights in the WinCC user administration for the user that will run the script (typically
Administratoror a custom role with Runtime - Start/Stop rights). - For the C-script path, Microsoft OLE DB / ODBC drivers for Access (ACE.OLEDB.12.0 or Microsoft.Jet.OLEDB.4.0) must be present. Windows 10 / Server 2016+ ships the 64-bit ACE driver; 32-bit WinCC still requires the 32-bit ACE redistributable.
2. WinCC Project Version Field: Where It Lives
Open WinCC Explorer, right-click the project node, and choose Properties. The dialog exposes a Version field (in some builds labelled Project version or Project revision). Whatever string is entered there is written to the PROJECTVERSION column of the MCPTPROJECT table in the project's CS database when the project is saved or compiled.
The CS database is created automatically at <ProjectPath>\<ProjectName>.mdf for SQL Server backed projects, or <ProjectPath>\<ProjectName>.MDB for the default Access file. A system DSN with the same name as the project is registered during project activation; this DSN is the handle used by the script.
3. The MCPTPROJECT Table Layout
| Column Index (0-based) | Field Name (approx.) | Content |
|---|---|---|
| 0 | PROJECTNAME | WinCC project name |
| 1 | PROJECTPATH | Full filesystem path of the .MCP |
| 2 | PROJECTVERSION | Free-form version string entered in project properties |
| 3+ | CREATIONDATETIME, COMPUTERNAME, … | Project creation metadata |
Because column order can change between WinCC service packs, the production code shown below uses the field name rather than the index. The original posting from the WinCC community used index 2 (the third field) on WinCC V7.0 SP3. If you upgrade, verify with Microsoft Access or a quick SELECT that PROJECTVERSION is still column index 2 or switch to a named lookup.
4. C-Script: Production-Ready Implementation
The following function returns the project version as a char*. It is the same approach the community posted, hardened with explicit error handling, named field access, and safe buffer sizes.
//----------------------------------------------------------------------
// Filename: DetermineVersionNumber.fct
// Purpose : Return the WinCC project version string from the CS DB.
// Caller : Trigger on project open or store result in internal tag.
// Tested : WinCC V7.4 SP1, V7.5 SP2 (32-bit project)
//----------------------------------------------------------------------
#include "apdefap.h"
#include "apdb.h" // ADODB wrapper, optional
// ODK prototypes (also in DMdef.h, supplied with WinCC ODK)
extern "C" {
BOOL DMGetRuntimeProjectA(LPSTR szProjectName, DWORD dwSize, CMN_ERRORA* lpError);
BOOL DMGetProjectInformationA(LPSTR szProjectName, DM_PROJECT_INFO* lpInfo, CMN_ERRORA* lpError);
}
char* DetermineVersionNumber()
{
static char szVersion[256]; // static so caller can read after return
char szProject[256] = {0};
char szConn[512] = {0};
char szQuery[256] = {0};
CMN_ERRORA err = {0};
DM_PROJECT_INFO info = {0};
memset(szVersion, 0, sizeof(szVersion));
// ---- Step 1: get the runtime project name and its DSN
if (!DMGetRuntimeProjectA(szProject, sizeof(szProject), &err)) {
printf("DMGetRuntimeProjectA failed (0x%08X)\r\n", err.dwError1);
return szVersion;
}
if (!DMGetProjectInformationA(szProject, &info, &err)) {
printf("DMGetProjectInformationA failed (0x%08X)\r\n", err.dwError1);
return szVersion;
}
sprintf(szConn, "DSN=%s;", info.szDSNName);
sprintf(szQuery, "SELECT PROJECTVERSION FROM MCPTPROJECT");
// ---- Step 2: open the CS database through ADODB
__object* con = __object_create("ADODB.Connection");
__object* rs = __object_create("ADODB.RecordSet");
con->Open(szConn);
if (con->State == 0) {
printf("DB connection failed for DSN=%s\r\n", info.szDSNName);
__object_delete(rs);
__object_delete(con);
return szVersion;
}
rs->Open(szQuery, con, 1); // adOpenKeyset = 1
if (!rs->EOF) {
// Use the named field to be robust against column re-ordering.
strncpy(szVersion, (const char*)rs->Fields("PROJECTVERSION"),
sizeof(szVersion) - 1);
}
rs->Close();
con->Close();
__object_delete(rs);
__object_delete(con);
return szVersion;
}
4.1 Wiring the C-Script into the Project
- Open the WinCC project and choose Global Scripts → C-Editor.
- Create a new function, paste the code above, and save as
DetermineVersionNumber.fct. - Create a standard function (no return value) named e.g.
Init_ProjectVersionthat callsDetermineVersionNumber()and writes the result to an internal text tag. - Open Project Properties → Startup and add the function to the Global Script Runtime - On Project Start actions list so the tag is populated before the first picture is loaded.
4.2 Why an Internal Tag, Not a Direct Call
Calling a C-function from every picture is expensive and triggers the ADODB round trip each time. By storing the result in a 256-byte internal text tag once at startup, every faceplate, alarm, and VBS action can read it in microseconds with GetTagChar("@ProjectVersion"). The internal tag also makes the value visible to the WinCC tag simulator and to the Tag Logging archive, which is useful when the audit trail must record which project version triggered an event.
5. VBScript Alternatives
VBS in WinCC runtime does not expose DMGetRuntimeProjectA directly. Three practical routes exist, in order of robustness.
5.1 Read the Internal Tag Populated by the C-Script
' VBS in a button or faceplate
Dim sVer
sVer = HMIRuntime.Tags("@ProjectVersion").Read
HMIRuntime.Trace "Project version is: " & sVer & vbCrLf
This is the recommended pattern. The C-script does the database work once; VBS only reads a tag, so the same value is available everywhere from any picture.
5.2 Use the Internal Tag DatasourceNameRT
WinCC exposes the runtime DSN name as an internal tag. Combined with a stored procedure or a pre-built query it can be used to derive the project name, but it does not directly contain the version, so this is only useful when the project version is appended to the DSN (a common deployment convention).
Dim sDSN
sDSN = HMIRuntime.Tags("DatasourceNameRT").Read ' e.g. "MyProject_V3_2_1"
HMIRuntime.Trace "Runtime DSN: " & sDSN & vbCrLf
5.3 Direct ADODB from VBS
VBS in WinCC has full access to ADODB.Connection via the global CreateObject equivalent. You can therefore perform the same query as the C-script, with the caveat that VBS error handling is lighter and there is no static buffer:
' VBS action - call once at startup
Function GetProjectVersion()
Dim sVer, sDSN, sConn
On Error Resume Next
' The DSN equals the project name; retrieve it from the WinCC API.
sDSN = HMIRuntime.Tags("DatasourceNameRT").Read
sConn = "DSN=" & sDSN & ";"
Dim con, rs
Set con = CreateObject("ADODB.Connection")
con.Open sConn
If con.State = 0 Then
HMIRuntime.Trace "VBS: DB connection failed" & vbCrLf
GetProjectVersion = ""
Exit Function
End If
Set rs = con.Execute("SELECT PROJECTVERSION FROM MCPTPROJECT")
If Not rs.EOF Then sVer = rs.Fields("PROJECTVERSION").Value
rs.Close : con.Close
Set rs = Nothing : Set con = Nothing
GetProjectVersion = sVer
End Function
' Write the result into the internal tag
HMIRuntime.Tags("@ProjectVersion").Write GetProjectVersion()
DatasourceNameRT internal tag is supplied automatically by WinCC; you do not need to declare it manually. If you do not see it in the tag list, check that the project has been activated at least once and that the internal tag group System is visible.6. Configuring the Project Version Property
The script is only as good as the data the engineer types in. A disciplined versioning scheme prevents mystery values such as final, latest, or an empty string appearing in the field.
- Use a three-part semantic version, e.g.
2.4.1, optionally suffixed with a build counter:2.4.1+build-2025-04-12. - Restrict the dialog field to a regex via a WinCC change-control procedure; the WinCC UI itself does not validate the string.
- Reproduce the value in the file name of the
.MCarchive, in the ESD file name, and on the cabinet label so field staff can match the project to the HMI. - Update the version before the first compile on a new revision; re-compiling does not retroactively update the field if the dialog is closed without saving.
7. Exposing the Version to Operators
A common requirement is to print the version on the System Info picture so that the operator can quote it during a service call. To do this:
- Create the internal text tag
@ProjectVersionwith length 256 in the Internal tags group. - Add an I/O field or a static text element to the system picture and link its Output Value property to
@ProjectVersion. - Optionally append a Configuration property that triggers a tag logging entry whenever the tag changes, so the version change is captured the first time the new project is started.
8. Verification Steps
- Open the WinCC project, enter
TEST-1.0.0in Project Properties → Version, and save. - Compile the project and start runtime.
- Open Global Script → Debug and confirm the GSC Diagnostics window prints the version string without the DB connection failed line.
- In the system picture, the I/O field bound to
@ProjectVersionshould displayTEST-1.0.0. - Close runtime, change the version to
TEST-1.0.1, recompile, restart runtime, and confirm the displayed value updates without restarting the OS or the WinCC service. - Inspect the project.MDB file directly with Microsoft Access and verify the
MCPTPROJECT.PROJECTVERSIONrow matches the value displayed in runtime.
9. Troubleshooting Matrix
| Symptom | Likely Cause | Fix |
|---|---|---|
DB Connection Failed printed in GSC Diagnostics |
DSN not registered, or 32-bit/64-bit driver mismatch | Activate the project once so the DSN is created. Install the matching bitness of ACE.OLEDB.12.0 (32-bit WinCC = 32-bit driver). |
| Empty string returned even though the project property is filled | Column index changed after a service pack upgrade | Switch the SELECT to use the named field PROJECTVERSION instead of Fields(2). |
| Function compiles but is never called | Function not added to the On Project Start actions list | Open Project Properties → Startup → Global Script Runtime and add the function; re-activate the project. |
| Value visible in C-debug but VBS returns empty | Internal tag has the wrong type (binary/text) or wrong length | Declare the tag as Text tag, 16-bit character set, length 256. |
DMGetRuntimeProjectA failed 0x80040E14 |
WinCC ODK runtime not initialized | Ensure DMClient.dll is registered with regsvr32 on the runtime station. Confirm the ODK runtime option is installed. |
| Script returns the value of the wrong project on a redundant pair | DSN on the partner server points to a different project folder | Check the project path in Project Properties → General on both servers and replicate the project folder before redundancy switch. |
Error 2147467259 (80004005) when opening the MDB |
Access denied, file is read-only, or path contains spaces and is not quoted | Grant the WinCC runtime user modify rights on the project folder; avoid spaces in the project path or quote the DSN value. |
10. Cross-Platform Notes
| Platform | Recommended Path | Comments |
|---|---|---|
| WinCC V7.0 SP3 to V7.5 SP2 | C-script with ADODB, internal tag, VBS reads tag | Default Access CS database. Code in this article applies directly. |
| WinCC V7.4 SP1 with SQL Server CS | Same C-script, change connection string to Provider=SQLNCLI11;Server=...;Database=<CS>;Trusted_Connection=Yes
|
Used for multi-user engineering. |
| WinCC Professional (TIA Portal V15-V18) | Use SWB → Project Information → Project Version read via HMIRuntime.SysFct.GetProjectInformation or expose the value through a configured tag |
No direct DB access; the version is exposed by the HMI runtime API. |
| WinCC Unified (V16+) | JavaScript: HMIRuntime.RuntimeFunctions.GetProjectVersion() or read a configured tag |
No ADODB, no C-scripts. VBS not available. |
11. Performance and Security Considerations
The CS database is opened on a local ODBC DSN, so the round trip is on the order of 1-5 ms on a modern Windows station, but the cost grows if the DSN points across a network. The startup-time cost is negligible, but calling the C-function from a frequently fired cyclic action (e.g. 100 ms) will consume one connection per call and will eventually fail when the connection pool is exhausted. Always read the cached internal tag from cyclic actions.
Restrict read access to the CS database folder. The .MDB contains every project property, including paths, user names, and any value placed in the project notes. If the project has proprietary tag names, lock the file with NTFS ACLs. For SQL-backed CS, the db_owner role on the CS database is sufficient for the script; do not grant sysadmin to the runtime account.
12. Frequently Asked Questions
Does the version field update automatically when I edit the project?
No. WinCC writes the value of the Project Properties → Version field to the MCPTPROJECT table when the project is saved or compiled, but the field itself is not auto-incremented. The engineer must update it before each compile cycle; a one-line change-management SOP that forces a version bump before every release prevents stale values.
Why does the C-script return an empty string on the first runtime start?
Two common causes: (1) the DSN was not registered yet because the project has never been activated, or (2) the column index changed in a newer service pack. Open the project.MDB with Microsoft Access, look at the MCPTPROJECT table, and confirm that the third column is still labelled PROJECTVERSION. Switch to the named field Fields("PROJECTVERSION") for long-term robustness.
Can I read the project version from a WinCC Unified faceplate?
Yes. WinCC Unified exposes a JavaScript runtime API. Use HMIRuntime.RuntimeFunctions.GetProjectVersion() on a screen load event, or read a pre-configured internal tag that you populate via a startup script. ADODB and the C-script path are not available in Unified.
Is there a way to log the project version automatically at runtime start?
Yes. In the C-script On Project Start action, after writing the value to @ProjectVersion, also call UserArchiveWrite or simply append a comment line to an alarm message via MSRTSetCommentA. Combined with Tag Logging's Comment field, this gives a permanent audit trail of which project revision was running when an event occurred.
What happens on a redundant WinCC server pair if the version is changed on only one side?
When the standby server takes over, its CS database determines the value, so a half-updated pair will alternate between the two versions during failover. Replicate the .MCP and the .MDB together as a single unit, and verify with the Redundancy Control diagnostics that both partners report the same value after the change has been deployed.