1. Overview
Siemens WinCC (TIA Portal / V7) exposes runtime data through three well-supported channels: an internal OPC DA Server (built-in, no extra license), the Connectivity Pack / WinCC DataMonitor (OLE DB / SOAP / OPC XML / WinCC OLE DB provider), and the Industrial Data Bridge (IDB) add-on for declarative tag-to-database bridging. A C# application can read and write WinCC tags through any of these paths and, in the same process, persist values to Microsoft SQL Server using ADO.NET or the WinCC SQL Provider.
This reference covers all four integration paths, the DCOM configuration required to traverse a LAN, the error matrix that appears in field deployments, and the C# code skeleton for an OPC DA 3.0 client built against OPC Foundation .NET API or OpcNetApi.
2. Architecture Options
| Method | Direction | WinCC Add-on | C# Stack | Best For |
|---|---|---|---|---|
| OPC DA 3.0 (in-process COM) | Bidirectional tags | None (built-in) | OpcNetApi / OPC Foundation .NET | Real-time tag read/write, low latency |
| Connectivity Pack / DataMonitor OLE DB | Read-only archive | WinCC Connectivity Pack or DataMonitor | ADO.NET + OLE DB Provider for WinCC | Historical / alarm queries |
| Industrial Data Bridge (IDB) | Bidirectional, declarative | IDB license + dongle | No client code needed; WinCC config only | Plant-floor tag mirroring to SQL |
| VBS + ADODB inside WinCC | Bidirectional, scheduled | None (WinCC Scripting) | WinCC-side VBScript | Lightweight polling without external C# app |
For a C# application on a remote workstation, the canonical path is OPC DA over DCOM. For historical reads from the WinCC archive database, use the WinCC OLE DB Provider through Connectivity Pack. For a managed, point-and-click bridge without writing any C# code, use IDB.
3. Prerequisites
- WinCC Runtime V7.2 / V7.3 / V7.4 / V7.5 (or WinCC Professional in TIA Portal) installed and running in Runtime.
- The WinCC OPC DA Server process
OPCServer.WinCCregistered as a local COM service. Verify withopcenum.exeon the WinCC station - the server should appear under OPC Servers > OPCServer.WinCC. - Windows user accounts with identical username and password on both the WinCC station and the C# client station. Mismatched credentials are the leading cause of Access is Denied (0x80070005) failures.
- DCOM configured on both machines (see Section 9).
- For SQL Server integration: SQL Server 2014 / 2016 / 2017 / 2019 (Express is sufficient for tag mirroring), TCP port 1433 reachable, SQL authentication or trusted Windows authentication.
- C# development environment: Visual Studio 2010 or later, .NET Framework 4.x or .NET 6/7/8 with COM interop enabled.
4. Method 1 - OPC DA Client in C#
The OPC Foundation .NET API (or the older OpcNetApi.dll) allows any .NET application to enumerate the WinCC OPC server, browse tags, subscribe to data changes, and synchronously read/write values.
4.1 Add References
-
OpcNetApi.dll(v2.x) - browse, sync I/O, subscription -
OpcNetApi.Com.dll- COM interop wrapper - Add
using Opc;,using Opc.Da;
4.2 Connect to WinCC OPC Server
using Opc;
using Opc.Da;
// Replace 192.168.2.252 with the WinCC Runtime station IP or hostname
string serverUrl = "opcda://192.168.2.252/OPCServer.WinCC";
Opc.Da.Server server = null;
try
{
server = new Opc.Da.Server(new OpcCom.Factory(), null);
server.Url = new Opc.URL(serverUrl);
server.Connect();
// server.IsConnected == true on success
}
catch (OpcConnectException ex)
{
// 0x80070005 = Access Denied (DCOM)
// 0x80040154 = Class not registered (OPC service not running)
// 0x800706BA = RPC server unavailable (firewall / service down)
Console.WriteLine($"OPC connect failed: 0x{ex.Result.Code:X8}");
}
4.3 Browse and Read Tags
// Browse the flat namespace (use BrowseFilters.Flat)
BrowsePosition position = null;
BrowseElement[] elements = server.Browse(
new ItemIdentifier(""),
new BrowseFilters { BrowseFilter = browseFilter.flat, ElementNameFilter = null },
out position);
foreach (BrowseElement el in elements)
{
Item item = new Item(new ItemIdentifier(el.ItemName), true, 0);
ItemValueResult[] result = server.Read(new Item[] { item });
Console.WriteLine($"{el.ItemName} = {result[0].Value}");
}
4.4 Subscribe to Data Changes
Subscription subscription = null;
SubscriptionState state = new SubscriptionState
{
Name = "WinCC_Sub",
Active = true,
UpdateRate = 250, // ms
Deadband = 0.0f,
KeepAlive = 1000 // ms
};
subscription = (Subscription)server.CreateSubscription(state);
Item[] items = new Item[]
{
new Item(new ItemIdentifier("S7_Program::DB1::Tag1"), true, 0),
new Item(new ItemIdentifier("S7_Program::DB1::Tag2"), true, 0)
};
subscription.AddItems(items);
subscription.DataChanged += OnDataChanged;
// Handler signature
private static void OnDataChanged(object sender, DataChangedEventArgs e)
{
foreach (ItemValueResult iv in e.Values)
Console.WriteLine($"Change: {iv.ItemName} = {iv.Value} @ {iv.Timestamp}");
}
4.5 Write a Value
ItemValue itemValue = new ItemValue
{
ItemName = "S7_Program::DB1::Tag1",
Value = 1234
};
IdentifiedResult[] writeResult = server.Write(new ItemValue[] { itemValue });
// writeResult[0].ResultId.Succeeded == true on success
TagPrefix::TagName (e.g. S7_Program::DB1::Motor_Speed). External tags configured in the WinCC Tag Management appear with their configured name. Always verify the exact name via OPC browsing before hardcoding.5. Method 2 - Connectivity Pack / DataMonitor (OLE DB)
The WinCC Connectivity Pack (license 6AV6371-1DR07-... or as part of DataMonitor) exposes the runtime archive, alarm log, and tag table through an OLE DB provider accessible to any ADO.NET consumer.
5.1 Connection String
Provider=WinCCOLEDBProvider.1;
Catalog=CC_Engineering_15_08_19_12_00_00;
Data Source=192.168.2.252\WinCC
The Catalog is the WinCC project name; Data Source is the SQL Server instance created during WinCC install (default \WinCC).
5.2 Read Archived Process Values
using (OleDbConnection conn = new OleDbConnection(connString))
{
conn.Open();
string sql = @"SELECT * FROM TAG:R,'S7_Program::DB1::Motor_Speed','0000-00-00 00:10:00.000','0000-00-00 00:11:00.000'";
using (OleDbCommand cmd = new OleDbCommand(sql, conn))
using (OleDbDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
Console.WriteLine($"{dr["Timestamp"]} {dr["RealValue"]}");
}
}
Read the official WinCC Connectivity Pack manual for the full SQL-like syntax: Siemens Entry ID 102628683 - WinCC Connectivity Pack documentation.
6. Method 3 - Industrial Data Bridge (IDB)
IDB is a Windows service shipped with WinCC that can mirror tags from any OPC DA / OPC UA source (including OPCServer.WinCC) into SQL Server, Oracle, MySQL, SAP RFC, or a text file - with no custom code. The agent is configured through the IDB Configurator GUI on the WinCC station.
Official Siemens entry for IDB: Entry ID 73968374 - WinCC Industrial Data Bridge. Licensing is per station via the Automation License Manager (ALM).
When to choose IDB over a C# client:
- No C# developer is available on the IT side.
- Tag list is stable and small (< 5000 tags).
- You need guaranteed-store-and-forward behaviour during network outages.
7. Method 4 - VBScript with ADODB (no external C# app)
If the integration target is just a SQL table and there is no need for an external C# application, a WinCC Global Script can perform the writes. In the WinCC Graphics Designer, add a Global Action running every N seconds:
Dim conn, rs, sql
Set conn = CreateObject("ADODB.Connection")
conn.Provider = "SQLOLEDB"
conn.Properties("Data Source").Value = "192.168.2.20\SQLEXPRESS"
conn.Properties("Initial Catalog").Value = "PlantHistorian"
conn.Properties("User ID").Value = "sa"
conn.Properties("Password").Value = "secret"
conn.Open
sql = "INSERT INTO TagLog(TagName, Value, TS) VALUES('Motor_Speed', " & _
HMIRuntime.Tags("Motor_Speed").Read & ", GETDATE())"
conn.Execute(sql)
conn.Close
Set conn = Nothing
8. SQL Server Integration from the C# Host
Once the C# app is reading from WinCC, persist values to SQL Server with System.Data.SqlClient or Microsoft.Data.SqlClient.
using (var sql = new SqlConnection("Server=192.168.2.20\\SQLEXPRESS;Database=PlantHistorian;Integrated Security=SSPI;"))
{
sql.Open();
using (var cmd = new SqlCommand("INSERT INTO dbo.TagLog (TagName, Value, TS) VALUES (@n, @v, @t)", sql))
{
cmd.Parameters.AddWithValue("@n", iv.ItemName);
cmd.Parameters.AddWithValue("@v", iv.Value);
cmd.Parameters.AddWithValue("@t", iv.Timestamp);
cmd.ExecuteNonQuery();
}
}
For high-throughput applications, batch the inserts and use SqlBulkCopy:
DataTable dt = new DataTable();
dt.Columns.Add("TagName", typeof(string));
dt.Columns.Add("Value", typeof(object));
dt.Columns.Add("TS", typeof(DateTime));
// fill dt...
using (var bulk = new SqlBulkCopy(sql))
{
bulk.DestinationTableName = "dbo.TagLog";
bulk.WriteToServer(dt);
}
9. DCOM Configuration (Required for Network OPC)
The single most common cause of Access Denied when a C# app calls opcda://<remote>/OPCServer.WinCC is incomplete DCOM configuration. Apply the following on both the WinCC station and the C# client station.
- Create a Windows user (e.g.
opcuser) on both machines with identical password. Add it to the local Distributed COM Users group and to Administrators on the WinCC station. - Run WinCC Runtime as that user: Start > WinCC > Autostart > Configure, or in services.msc change the logon of CCEServer, SIMATIC WinCC OPC Server, and SQL Server (WINCC) to
opcuser. - Open
dcomcnfg→ Component Services > Computers > My Computer > DCOM Config. - Right-click OPCServer.WinCC → Properties:
- General tab → Authentication Level: None (test lab) or Connect (production).
- Location tab → enable Run application on the following computer only.
-
Security tab → customize all three sections and grant
opcuserfull access. -
Identity tab → set This user and enter
opcuserand the password.
- In My Computer properties (top of the DCOM tree):
- Default Authentication Level: Connect.
- Default Impersonation Level: Identify.
- Open Windows Firewall with Advanced Security and create inbound rules for
C:\Windows\System32\dllhost.exe(DCOM launcher) andOPCServer.WinCC.exeon ports 135 (TCP) plus the dynamic RPC range. - Add the WinCC host's IP and the C# host's IP to Trusted Hosts in the registry only when using classic-impersonation (rare).
dcomcnfg → right-click My Computer → Properties → Default Properties tab. Toggle Enable Distributed COM on this computer. This forces a re-registration of DCOM listeners. Alternatively, use the OpcEnum tool shipped with the OPC Core Components to confirm the remote server is visible.10. Configuration Reference Table
| Parameter | Recommended Value | Notes |
|---|---|---|
| WinCC OPC Server ProgID | OPCServer.WinCC | Same for V7.2 to V7.5 |
| OPC Specification | DA 3.0 (DA 2.0 also works) | DA 1.0 lacks subscription |
| Update Rate | 250-1000 ms | Below 100 ms increases CPU |
| KeepAlive | 1000 ms | Detects dead subscriptions |
| Deadband | 0 (analog) or % of span | Filters noise on float tags |
| DCOM Auth Level | Connect | None acceptable only in test lab |
| Impersonation Level | Identify | Impersonate if write-back required |
| SQL TCP Port | 1433 | Use named instances + browser if non-default |
| SQL Auth | Windows integrated (preferred) | Use SQL login only if domain trust exists |
11. Troubleshooting Matrix
| Symptom | Hex Code | Likely Cause | Action |
|---|---|---|---|
| Access Denied on connect | 0x80070005 | DCOM user mismatch, ACL on OPCServer.WinCC | Reapply Section 9; verify identical user/password both sides |
| Class not registered | 0x80040154 | OPC server not running, firewall blocked | Check WinCC service; open port 135 + RPC range |
| RPC server unavailable | 0x800706BA | DCOM disabled, network unreachable | Enable DCOM on both; ping by hostname, not IP |
| Server not reachable on localhost but works on LAN IP | - | WinCC OPC binds only to NIC | Restart CCEServer after network change |
| Reads return Bad / quality = BadCommFailure | 0x80004005 | PLC connection down, wrong tag prefix | Check WinCC Channel Diagnostics |
| Subscription stops after 30 minutes | - | DCOM session timeout | Set KeepAlive < session timeout in component services |
| SQL login fails from WinCC station | - | Named-pipes disabled, wrong instance | Enable TCP in SQL Configuration Manager; test with SSMS |
| DataMonitor web page blank | - | IIS not installed / licensed | Reinstall DataMonitor; check ALM license |
12. Verification Procedure
- On the WinCC station, launch Start > Programs > Siemens Automation > SIMATIC > WinCC > OPC and start the OPC Scout. Add the local
OPCServer.WinCC, browse to a known tag, drag it into the view, and confirm the value updates. - From the C# client station, run OpcEnum (or OPC Foundation's
SampleClient) and add the remoteopcda://<WinCC>/OPCServer.WinCC. A successful add confirms DCOM works. - Start the C# application, verify it logs Connect: ok for every tag and that DataChanged fires at the expected UpdateRate.
- Confirm rows appear in the target SQL table:
SELECT TOP 10 * FROM dbo.TagLog ORDER BY TS DESC; - Pull the network cable between the WinCC station and the C# host. After the configured KeepAlive timeout, the client should log Server not connected. Reconnect the cable; subscription should auto-recover without restarting the C# app.
13. Security and Production Hardening
- Never leave Authentication Level = None on a production network - it disables RPC packet signing and allows trivial MITM attacks.
- Use a dedicated
opcuseraccount with no interactive login rights. - Restrict the SQL login to the
db_datawriterrole on the historian database only. - Encrypt traffic: OPC UA is supported in WinCC V7.3+ via the OPC UA Server option. Migrate from DA to UA when the C# stack supports it - no DCOM configuration is required.
- Audit firewall rules annually; Windows updates sometimes reset DCOM defaults.
14. Frequently Asked Questions
Do I need a separate software to connect WinCC to C#?
No. The WinCC OPC DA Server is built into every WinCC Runtime install - no extra license is required. You only need a free .NET OPC API library (OpcNetApi or the OPC Foundation .NET Standard wrappers) on the C# side, plus correctly configured DCOM. Connectivity Pack or Industrial Data Bridge are only required if you want historical archive access or managed tag bridging without writing C# code.
Why do I get Access Denied (0x80070005) when connecting from a remote C# app to opcda://192.168.2.252/OPCServer.WinCC?
The WinCC OPC server and the C# client must use Windows accounts with the same username and password. Verify that opcuser (or whichever account the WinCC services run under) exists on both machines, is in the local Distributed COM Users group, and that DCOM launch/access permissions on the OPCServer.WinCC COM object allow that account. See Section 9 for the full checklist.
Can a C# program write values back to WinCC via OPC DA?
Yes. The OPC DA 3.0 specification allows client writes; call Opc.Da.Server.Write with an ItemValue array and check the IdentifiedResult.ResultId for each tag. Set DCOM Impersonation Level to Impersonate if writes return 0x80070005 while reads succeed.
What is the difference between Connectivity Pack, DataMonitor, and Industrial Data Bridge?
Connectivity Pack provides OLE DB, SOAP, OPC XML, and OPC UA access to the WinCC archive for read/aggregation. DataMonitor is an Information Server add-on with web-based reports and the same OLE DB plumbing. Industrial Data Bridge (IDB) is a declarative, code-free tag-to-database mirror (SQL, Oracle, MySQL, SAP, text) configured through a GUI. IDB is best when you have many tags and no C# developer; Connectivity Pack is best for analytical/BI queries on historical data.
Can I avoid DCOM entirely and use OPC UA instead?
Yes, on WinCC V7.3 and later. Enable the OPC UA Server option in the WinCC project properties and add the Windows certificate to the trusted peers of the C# client. OPC UA runs over TCP port 4840, requires no DCOM, and is the recommended path for new deployments. See Siemens support entry 109769510 - WinCC OPC UA configuration.
How fast can a C# app poll WinCC tags over OPC DA?
With a 100 ms UpdateRate on a dedicated Windows 10/11 station, a 500-tag subscription runs comfortably at < 50 ms round-trip per read. The bottleneck is typically the WinCC channel driver, not the OPC layer. For sub-100 ms cycle times, use direct S7 communication via the S7 protocol in the C# app or move to OPC UA at 50-200 ms.