Resolving GetServerTagPrefix NULL Return in WinCC PCS7 @AreaButtons
The GetServerTagPrefix C-script function is widely used in WinCC / WinCC Professional / PCS 7 projects to resolve the distributed system server prefix of the picture currently in focus. Under WinCC V7.x, WinCC Professional (TIA Portal) and PCS 7 V8.x/V9.x, the function returns a valid prefix (::Server1::, ::Server2::, etc.) when invoked from a server-side picture window or a process picture that belongs to a server. The same call, however, frequently returns an empty string or NULL pointer when issued from an @AreaButtons toolbar, a @1001.@DESK SSM screen, or any picture that is part of the client's local project. This article documents the architectural reason for the failure, the WinCC runtime model that governs prefix resolution, and field-proven C-script workarounds using SSMGetSAPictureAndObjectName and manual prefix assembly.
1. Problem Description
When a C-script is attached to a button on the WinCC Area Buttons toolbar and calls GetServerTagPrefix(), the function pointer argument receives NULL (or an empty BSTR depending on the wrapper layer). The same call returns a valid server prefix when executed from:
- Process pictures stored on the OS server and opened in
PDLRTruntime - Faceplates opened by
PCS7_OpenGroupDisplay_V6from block icons - The alarm window OCX
loopinal.fctwhen it has been migrated to the server project
Typical signature used in the failing case:
char* szServerPrefix = NULL;
char* szTagPrefix = NULL;
char* szWindowPrefix = NULL;
int nResult = GetServerTagPrefix(&szServerPrefix, &szTagPrefix, &szWindowPrefix);
// nResult is non-zero, szServerPrefix remains NULL
Affected runtime objects commonly include @Areabuttons.pdl, the user-defined @1001.@DESK screen, and the SSM overview screen opened from the workplace area structure. The SSMGetSAPictureAndObjectName function works correctly in the same script and returns <Server prefix>::<picture name>, but the parser logic is more complex.
2. Root Cause Analysis
2.1 WinCC Runtime Picture Context
WinCC maintains an internal "current picture context" structure for every picture window instance. The server prefix, tag prefix, and window prefix are stored as three parallel string members of that structure. The GetServerTagPrefix (RT Professional) - WinCC documentation states that the function reads these three members and copies them into the caller-supplied buffer pointers.
The crucial detail is that these members are populated only when the picture owning the context is part of a server's project database. In a WinCC client / server topology, each OS server holds its own copy of the pictures assigned to it. When the client opens such a picture through the standard WinCC picture tree, the runtime context carries a non-empty server prefix equal to the server's configured prefix (for example ::OS_SERVER_1::).
2.2 SSM and Area Buttons Belong to the Client
Area Buttons are generated and stored in the client project. The file @Areabuttons.pdl lives in the client's GraCS directory. It is not synchronized from any server. The same is true for the standard screen @[email protected] and most user-defined @-prefixed screens that are part of the SSM (Screen Segment Manager / Workplace) area hierarchy.
Because the picture context backing the area button has no server in its project ownership chain, the szServerPrefix, szTagPrefix and szWindowPrefix fields of that context are never initialized. GetServerTagPrefix therefore either returns NULL pointers (C-API) or zero-length strings (VBScript wrapper) and the result code is non-zero. This is not a defect in the function but a direct consequence of the WinCC distributed architecture.
2.3 Why It Works in PCS7_OpenGroupDisplay_V6
The PCS 7 helper function PCS7_OpenGroupDisplay_V6 is called from a block icon sitting on a process picture that is owned by a server. Before opening the faceplate, the function captures the calling picture's context (which is valid), then internally invokes GetServerTagPrefix on that context. The returned prefix is used to construct the qualified tag name. When the same function is called from an area button, the calling context has no prefix, so the helper returns early or produces an invalid qualified name.
3. Diagnostic Procedure
- Open the affected picture in Graphics Designer and select the button with the failing C-script.
- In the property tree, navigate to Event > Mouse > Left Click (or the configured trigger) and confirm the action triggers
GetServerTagPrefix. - Open the WinCC project in the OS Server editor (WinCC Explorer > OS Project Editor) and inspect the Server prefix column. Verify the value is non-empty (typically
::<ServerName>::). - Verify the picture file location: right-click the picture in the WinCC Explorer graphics tree, choose Properties, and confirm the path. If the path resolves to the client project's
GraCSfolder, the function cannot return a prefix. - Add a temporary diagnostic line before the call:
The traced name will start withprintf("Picture=%s, Object=%s\r\n", lpszPictureName, lpszObjectName); // or in C: TRACE("Picture=%s, Object=%s\r\n", m_lpszPictureName, m_lpszObjectName);@for SSM / area screens, confirming a client-owned picture. - Open the WinCC diagnostics window (Start > Programs > Siemens Automation > WinCC > WinCC Diagnostics) and watch for runtime errors 0x80040E14 or similar when the button is pressed.
4. Verified Workarounds
4.1 Use SSMGetSAPictureAndObjectName and Parse the Result
The SSMGetSAPictureAndObjectName function is designed to run from the client project and returns the full picture-and-object reference, prefixed with the server prefix of the underlying picture. It is the recommended workaround for the area button scenario.
// C-script running in @Areabuttons.pdl
char* szResult = NULL;
SSMGetSAPictureAndObjectName(NULL, NULL, &szResult);
// szResult now contains "::OS_SERVER_1::@1001/@DESK/SomePicture.pdl::ObjectName"
char* pPrefix = strstr(szResult, "::");
if (pPrefix != NULL)
{
char* pEnd = strstr(pPrefix + 2, "::");
if (pEnd != NULL)
{
*pEnd = '\0';
// pPrefix now holds "::OS_SERVER_1::" - usable as server prefix
}
}
Notes on the parsing logic:
- Always search for the second
::token; the first occurrence may be inside the picture path if the picture was opened from a server with an explicit::in its name. - Copy the parsed string into a project-local buffer immediately; the pointer returned by the WinCC API is only valid until the next runtime function call.
- For PCS 7 V9.x, prefer
SSMGetSAPictureAndObjectNamefrom theSSMApiRT.dllexported inaplib.h; do not call the deprecatedSSMGetPictureAndObjectName.
4.2 Read the Server Prefix from a Stored Tag
For projects with a known static topology, write the server prefix into a WinCC internal tag (e.g. @ServerPrefix) on the server's startup script and read it from the area button:
// On OS Server startup (C-script, Global Script)
char* szPrefix = NULL;
GetServerTagPrefix(&szPrefix, NULL, NULL);
if (szPrefix != NULL)
{
SetTagChar("@ServerPrefix", szPrefix);
}
// szPrefix has form "::OS_SERVER_1::" - assign to the internal tag
On the area button side:
char szPrefix[64] = {0};
strcpy(szPrefix, GetTagChar("@ServerPrefix"));
// szPrefix is now the same prefix used on the server
This approach is the most robust when the same prefix must be reused for batch tag qualification across many C-scripts.
4.3 Use the Picture-in-Picture Reference
If the area button is acting on a specific screen hosted by a server, obtain the target picture context first and call GetServerTagPrefix on that context. Use SSMGetCurrentScreen to retrieve the screen handle, then GetServerTagPrefixEx (PCS 7 V9.0 and later) with the picture window handle as the first argument. The extended function takes a picture context handle and returns the prefix of the picture the handle points to, regardless of where the calling script is hosted.
4.4 Define the Prefix Manually for Single-Server Projects
In single-server (monoproject) installations or when redundancy is the only source of variation, hard-coding the prefix as a project constant avoids the issue entirely:
// Header file project_shared.h
#define SERVER_PREFIX "::OS_SERVER_1::"
#define TAG_PREFIX "TAG1::"
This pattern is acceptable for FAT (Factory Acceptance Test) and SAT (Site Acceptance Test) panels where the server name is fixed by contract.
5. Decision Matrix
| Calling Picture | Function Returns | Recommended Approach |
|---|---|---|
| Process picture on server | Valid server prefix | Use GetServerTagPrefix directly |
Faceplate opened by PCS7_OpenGroupDisplay_V6
|
Valid server prefix | Use GetServerTagPrefix directly |
| Alarm OCX (loopinal.fct) on server | Valid server prefix | Use GetServerTagPrefix directly |
@Areabuttons.pdl (client) |
NULL or empty | Use SSMGetSAPictureAndObjectName + parsing |
@1001.@DESK SSM screen (client) |
NULL or empty | Use SSMGetSAPictureAndObjectName + parsing |
Custom @-prefixed client picture |
NULL or empty | Read @ServerPrefix internal tag |
| Redundant pair, dynamic server name | NULL or empty from client | Use GetServerTagPrefixEx (PCS 7 V9.0+) |
6. Verification Steps
- Rebuild the WinCC runtime after modifying the C-script. In WinCC Explorer, right-click the OS server and select Rebuild all (for V7.x) or use Compile OS > Complete compilation (for TIA Portal).
- Activate the OS server, then the OS client. Wait for the client to report Connected to the server.
- Click the area button that previously failed. The WinCC diagnostics window must not log error 0x80040E14 (dispatch error) or similar.
- In the Tag Diagnosis window, browse for a tag whose qualified name uses the parsed prefix (e.g.
::OS_SERVER_1::TagName). Confirm the value updates. - Force a server failover (if a redundant pair is configured) and repeat the click test within 10 seconds of failover. The new server prefix must be picked up by the workaround within one client refresh cycle.
- For the SSMGetSAPictureAndObjectName variant, run the script under WinCC V7.5 with the Logging global action enabled to confirm the parsed prefix matches the configured server prefix string exactly (case-sensitive, including colons).
7. Common Pitfalls
-
Buffer reuse after API call. The pointer returned by
GetServerTagPrefixandSSMGetSAPictureAndObjectNamepoints into the runtime's internal picture context. Any subsequent runtime call may invalidate the memory. Always copy the result to a local buffer before performing string operations. -
VBScript and NULL. The VBScript wrapper
HMIRuntime.BaseScreenNamedoes not expose the prefix at all. Do not attempt to callGetServerTagPrefixthroughHMIRuntime; it is a C-API only. -
Server prefix synchronization. In redundant WinCC pairs, the standby server has a different prefix than the master. A hard-coded prefix in the client script will break on failover. Always use the
@ServerPrefixinternal tag or the extended API. -
Picture name argument confusion. Some legacy code passes the picture name as the first argument to
GetServerTagPrefix. The function has no string parameters; it has threechar**out-parameters. Passing a string by name corrupts the stack and produces an access violation rather than a NULL. -
Unicode build. In TIA Portal V16+ projects compiled with the Unicode runtime, the function exists in both ANSI (
GetServerTagPrefix) and Unicode (GetServerTagPrefixW) variants. Using the wrong variant in a mixed project causes silent NULL returns with no diagnostic entry.
8. Reference: Function Signature and Return Code
| Parameter | Type | Direction | Description |
|---|---|---|---|
pszServerPrefix |
char** |
Out | Pointer that receives the address of the server prefix string (e.g. ::OS_SERVER_1::). May be NULL if the function is called from a client-owned picture. |
pszTagPrefix |
char** |
Out | Pointer that receives the tag prefix (e.g. TAG1::). Same NULL semantics as above. |
pszWindowPrefix |
char** |
Out | Pointer that receives the window prefix. Same NULL semantics as above. |
| Return value | int |
Out | 0 on success, non-zero on error. The error code is not standardized across versions but is logged in the WinCC diagnostics file WinCC_Sys_01.log in the project's diagnose directory. |
Source: GetServerTagPrefix (RT Professional) - WinCC.
9. Compatibility Notes Across Versions
| WinCC / PCS 7 Version | Behavior | Recommended Workaround |
|---|---|---|
| WinCC V7.4 SP3 | NULL from client pictures |
SSMGetSAPictureAndObjectName parsing |
| WinCC V7.5 SP2 | NULL from client pictures, GetServerTagPrefixEx introduced |
Use Ex variant with picture window handle |
| WinCC Professional V15 / V16 (TIA) | Same NULL behavior; Unicode API available | Use GetServerTagPrefixW in Unicode scripts |
| WinCC Professional V17 / V18 (TIA) | Same NULL behavior; GetServerTagPrefixEx supported |
Ex variant preferred |
| PCS 7 V8.2 SP1 | Same NULL behavior on area buttons |
SSMGetSAPictureAndObjectName parsing |
| PCS 7 V9.0 / V9.1 | Same NULL behavior; Ex variant available |
Internal tag @ServerPrefix for dynamic topology |
10. Quick-Fix Checklist
- Confirm the calling picture is on the client project (path starts with the client
GraCSdirectory). - Replace direct
GetServerTagPrefixcalls withSSMGetSAPictureAndObjectNameplus the parsing snippet in section 4.1. - Copy the parsed string to a local buffer immediately to avoid use-after-free.
- If the project uses a redundant server pair, use the
@ServerPrefixinternal tag updated on server startup. - Compile and rebuild the OS project, activate runtime, and test on a live picture.
- Verify failover behavior if redundancy is in scope.
Why does GetServerTagPrefix return NULL from @AreaButtons in WinCC PCS 7?
Because @AreaButtons and other @-prefixed SSM pictures belong to the client project, not to any OS server. The picture context backing the button has no server prefix in its internal fields, so the three out-parameters of GetServerTagPrefix remain NULL or empty. This is by design, not a bug.
Which function can I call instead from an area button to obtain the server prefix?
Use SSMGetSAPictureAndObjectName, which runs in the client context and returns the full reference of the form ::ServerName::Picture.pdl::Object. Parse the substring between the first and second :: tokens to extract the server prefix.
Is there a difference between GetServerTagPrefix in WinCC V7.x and WinCC Professional (TIA Portal)?
The behavior is identical: NULL is returned from client-owned pictures. TIA Portal adds a Unicode variant GetServerTagPrefixW and an extended variant GetServerTagPrefixEx that accepts a picture window handle and returns the prefix of that target picture even when called from the client.
How do I handle a redundant server pair where the server name changes on failover?
Write the current server prefix into an internal WinCC tag (for example @ServerPrefix) on the OS server's startup script using GetServerTagPrefix. Read this tag from the area button script. Update the tag again from the standby server's startup after failover; the client refresh cycle picks it up within one polling interval.
Can GetServerTagPrefix be called from a VBScript on an area button?
No. GetServerTagPrefix is a C-API function exposed only in the C-scripting environment. VBScript on area buttons does not have direct access; use SSMGetSAPictureAndObjectName and parse the result, or store the prefix in an internal tag and read it via HMIRuntime.Tags.