tia-csharp-common
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTIA Portal Openness C# — Common Foundation
TIA Portal Openness C# — 通用基础
Source: TIA Portal Openness General Functions Manual (03/2026, V21);
V21 IntelliSense XML documentation files (PublicAPI\V21\net48*.xml)
来源:TIA Portal Openness通用功能手册(2026年3月,V21版本);V21智能感知XML文档文件(PublicAPI\V21\net48*.xml)
V21 modular assembly architecture
V21模块化程序集架构
V21 splits the API across multiple DLLs instead of a single .
Every project needs ; add domain DLLs as required.
Referencing the wrong DLL (or omitting one) causes at runtime.
Siemens.Engineering.dllSiemens.Engineering.Base.dllTypeLoadExceptionFull mapping: Seefor the V21 namespace → DLL → domain skill table, cross-assembly warnings, and csproj patterns.references/assembly-namespace-map.md
V21将API拆分到多个DLL中,而非单一的。每个项目都需要;可根据需求添加领域相关的DLL。引用错误的DLL(或遗漏必要DLL)会在运行时引发。
Siemens.Engineering.dllSiemens.Engineering.Base.dllTypeLoadException完整映射: 请查看获取V21的命名空间→DLL→领域技能对照表、跨程序集警告以及csproj配置模板。references/assembly-namespace-map.md
Namespaces by assembly
按程序集划分的命名空间
Only import what is actually used. The list below covers the most commonly needed
namespaces. The mapping file summarizes the XML-documented namespaces across all 16
installed V21 PublicAPI DLLs.
Siemens.Engineering.Base.dll (always required):
csharp
using Siemens.Engineering; // TiaPortal, Project, ExclusiveAccess, Transaction, events, exceptions
using Siemens.Engineering.Compiler; // CompilerResult
using Siemens.Engineering.Compare; // CompareResult
using Siemens.Engineering.Connection; // connection objects between devices
using Siemens.Engineering.CrossReference; // cross-reference queries
using Siemens.Engineering.Download; // DownloadProvider, DownloadConfiguration
using Siemens.Engineering.Download.Configurations; // device-specific download configs (★ also in Step7 + Startdrive)
using Siemens.Engineering.HW; // Device, DeviceItem, Subnet, Node, IoSystem (★ also in Step7)
using Siemens.Engineering.HW.CommunicationConnections; // communication connection configs
using Siemens.Engineering.HW.Extensions; // extension methods on HW objects
using Siemens.Engineering.HW.Features; // SoftwareContainer, NetworkInterface (★ also in Step7)
using Siemens.Engineering.HW.HardwareCatalog; // hardware catalog access
using Siemens.Engineering.HW.Utilities; // HW utility helpers
using Siemens.Engineering.Library; // ProjectLibrary, GlobalLibrary
using Siemens.Engineering.Library.MasterCopies; // MasterCopy, MasterCopyFolder
using Siemens.Engineering.Library.Types; // LibraryType, LibraryTypeVersion
using Siemens.Engineering.Multiuser; // LocalSession, ProjectServer
using Siemens.Engineering.Online; // OnlineProvider, OnlineState
using Siemens.Engineering.Online.Configurations; // OnlineConfiguration, TLS/authentication callbacks
using Siemens.Engineering.Security; // SecurityController, certificates
using Siemens.Engineering.Settings; // TIA Portal settings
using Siemens.Engineering.Umac; // UmacRole, UmacUser, UmacFunctionRight
using Siemens.Engineering.Upload; // StationUploadProvider, ParameterUploadProvider
using Siemens.Engineering.Upload.Configurations; // upload configs (★ also in Startdrive)
using Siemens.Engineering.VersionControl; // workspace and version control providersSiemens.Engineering.Step7.dll (PLC operations):
csharp
using Siemens.Engineering.Cax; // CAx import/export
using Siemens.Engineering.SW; // PlcSoftware
using Siemens.Engineering.SW.Alarm; // PlcAlarm, AlarmClass
using Siemens.Engineering.SW.Alarm.TextLists; // alarm text lists
using Siemens.Engineering.SW.Blocks; // PlcBlock, OB, FB, FC, GlobalDB, InstanceDB, ArrayDB
using Siemens.Engineering.SW.Blocks.Interface; // block interface access
using Siemens.Engineering.SW.ExternalSources; // PlcExternalSource
using Siemens.Engineering.SW.Loader; // program loader
using Siemens.Engineering.SW.OpcUa; // OPC UA server interface
using Siemens.Engineering.SW.Supervision; // supervision alarms, operator messages
using Siemens.Engineering.SW.Tags; // PlcTagTable, PlcTag, PlcConstant
using Siemens.Engineering.SW.TechnologicalObjects; // technology objects
using Siemens.Engineering.SW.TechnologicalObjects.Motion; // motion axes (★ also in Startdrive)
using Siemens.Engineering.SW.Types; // PlcType, PlcStruct
using Siemens.Engineering.SW.Units; // SoftwareUnit, CodeBlock, DataBlock
using Siemens.Engineering.SW.WatchAndForceTables; // PlcWatchTable, PlcForceTableSiemens.Engineering.WinCC.dll (classic HMI):
csharp
using Siemens.Engineering.Hmi; // HmiTarget (★ also in WinCC.Extension)
using Siemens.Engineering.Hmi.Alarm; // DiscreteAlarm, AnalogAlarm
using Siemens.Engineering.Hmi.Communication; // HmiConnection
using Siemens.Engineering.Hmi.Cycle; // cycle settings
using Siemens.Engineering.Hmi.Dynamic; // dynamization
using Siemens.Engineering.Hmi.Faceplate; // faceplate types
using Siemens.Engineering.Hmi.Globalization; // language/translation
using Siemens.Engineering.Hmi.Logging; // DataLog, LoggingTag
using Siemens.Engineering.Hmi.Recipe; // Recipe, RecipeElement
using Siemens.Engineering.Hmi.RuntimeScripting; // VBScript
using Siemens.Engineering.Hmi.Screen; // HmiScreen, ScreenTemplate, ScreenPopup + all elements
using Siemens.Engineering.Hmi.Tag; // HmiTag, HmiTagTable
using Siemens.Engineering.Hmi.TextGraphicList; // text/graphic lists
using Siemens.Engineering.Hmi.Theming; // HMI themesSiemens.Engineering.Startdrive.dll (SINAMICS drives):
csharp
using Siemens.Engineering.MC.Drives; // DriveObject, DriveParameter, Telegram
using Siemens.Engineering.MC.Drives.DFI; // DriveFunctionInterface, Commissioning
using Siemens.Engineering.MC.Drives.Enums; // drive enumerations
using Siemens.Engineering.MC.Drives.SecurityObjects; // drive encryption, UMACSiemens.Engineering.Safety.dll (F-system):
csharp
using Siemens.Engineering.Safety; // safety operations仅导入实际用到的命名空间。以下列表涵盖最常用的命名空间。映射文件汇总了已安装的16个V21 PublicAPI DLL中所有带XML文档的命名空间。
Siemens.Engineering.Base.dll(必须引用):
csharp
using Siemens.Engineering; // TiaPortal、Project、ExclusiveAccess、Transaction、事件、异常
using Siemens.Engineering.Compiler; // CompilerResult
using Siemens.Engineering.Compare; // CompareResult
using Siemens.Engineering.Connection; // 设备间的连接对象
using Siemens.Engineering.CrossReference; // 交叉引用查询
using Siemens.Engineering.Download; // DownloadProvider、DownloadConfiguration
using Siemens.Engineering.Download.Configurations; // 设备专属下载配置(★同时适用于Step7 + Startdrive)
using Siemens.Engineering.HW; // Device、DeviceItem、Subnet、Node、IoSystem(★同时适用于Step7)
using Siemens.Engineering.HW.CommunicationConnections; // 通信连接配置
using Siemens.Engineering.HW.Extensions; // HW对象的扩展方法
using Siemens.Engineering.HW.Features; // SoftwareContainer、NetworkInterface(★同时适用于Step7)
using Siemens.Engineering.HW.HardwareCatalog; // 硬件目录访问
using Siemens.Engineering.HW.Utilities; // HW实用工具
using Siemens.Engineering.Library; // ProjectLibrary、GlobalLibrary
using Siemens.Engineering.Library.MasterCopies; // MasterCopy、MasterCopyFolder
using Siemens.Engineering.Library.Types; // LibraryType、LibraryTypeVersion
using Siemens.Engineering.Multiuser; // LocalSession、ProjectServer
using Siemens.Engineering.Online; // OnlineProvider、OnlineState
using Siemens.Engineering.Online.Configurations; // OnlineConfiguration、TLS/身份验证回调
using Siemens.Engineering.Security; // SecurityController、证书
using Siemens.Engineering.Settings; // TIA Portal设置
using Siemens.Engineering.Umac; // UmacRole、UmacUser、UmacFunctionRight
using Siemens.Engineering.Upload; // StationUploadProvider、ParameterUploadProvider
using Siemens.Engineering.Upload.Configurations; // 上传配置(★同时适用于Startdrive)
using Siemens.Engineering.VersionControl; // 工作区与版本控制提供器Siemens.Engineering.Step7.dll(PLC操作):
csharp
using Siemens.Engineering.Cax; // CAx导入/导出
using Siemens.Engineering.SW; // PlcSoftware
using Siemens.Engineering.SW.Alarm; // PlcAlarm、AlarmClass
using Siemens.Engineering.SW.Alarm.TextLists; // 报警文本列表
using Siemens.Engineering.SW.Blocks; // PlcBlock、OB、FB、FC、GlobalDB、InstanceDB、ArrayDB
using Siemens.Engineering.SW.Blocks.Interface; // 块接口访问
using Siemens.Engineering.SW.ExternalSources; // PlcExternalSource
using Siemens.Engineering.SW.Loader; // 程序加载器
using Siemens.Engineering.SW.OpcUa; // OPC UA服务器接口
using Siemens.Engineering.SW.Supervision; // 监控报警、操作员消息
using Siemens.Engineering.SW.Tags; // PlcTagTable、PlcTag、PlcConstant
using Siemens.Engineering.SW.TechnologicalObjects; // 工艺对象
using Siemens.Engineering.SW.TechnologicalObjects.Motion; // 运动轴(★同时适用于Startdrive)
using Siemens.Engineering.SW.Types; // PlcType、PlcStruct
using Siemens.Engineering.SW.Units; // SoftwareUnit、CodeBlock、DataBlock
using Siemens.Engineering.SW.WatchAndForceTables; // PlcWatchTable、PlcForceTableSiemens.Engineering.WinCC.dll(经典HMI):
csharp
using Siemens.Engineering.Hmi; // HmiTarget(★同时适用于WinCC.Extension)
using Siemens.Engineering.Hmi.Alarm; // DiscreteAlarm、AnalogAlarm
using Siemens.Engineering.Hmi.Communication; // HmiConnection
using Siemens.Engineering.Hmi.Cycle; // 周期设置
using Siemens.Engineering.Hmi.Dynamic; // 动态化
using Siemens.Engineering.Hmi.Faceplate; // 面板类型
using Siemens.Engineering.Hmi.Globalization; // 语言/翻译
using Siemens.Engineering.Hmi.Logging; // DataLog、LoggingTag
using Siemens.Engineering.Hmi.Recipe; // Recipe、RecipeElement
using Siemens.Engineering.Hmi.RuntimeScripting; // VBScript
using Siemens.Engineering.Hmi.Screen; // HmiScreen、ScreenTemplate、ScreenPopup及所有元素
using Siemens.Engineering.Hmi.Tag; // HmiTag、HmiTagTable
using Siemens.Engineering.Hmi.TextGraphicList; // 文本/图形列表
using Siemens.Engineering.Hmi.Theming; // HMI主题Siemens.Engineering.Startdrive.dll(SINAMICS驱动):
csharp
using Siemens.Engineering.MC.Drives; // DriveObject、DriveParameter、Telegram
using Siemens.Engineering.MC.Drives.DFI; // DriveFunctionInterface、调试
using Siemens.Engineering.MC.Drives.Enums; // 驱动枚举
using Siemens.Engineering.MC.Drives.SecurityObjects; // 驱动加密、UMACSiemens.Engineering.Safety.dll(F系统):
csharp
using Siemens.Engineering.Safety; // 安全操作Assembly loading — mandatory for standalone Openness apps
程序集加载——独立Openness应用的必备步骤
Not needed for Add-Ins. TIA Portal loads Add-In assemblies via its own loader. This section applies only to standalone console/desktop Openness applications.
插件无需此步骤。TIA Portal会通过自身加载器加载插件程序集。本节仅适用于独立控制台/桌面Openness应用。
V21 installation paths
V21安装路径
- Registry key: → value
HKLM\SOFTWARE\Siemens\Automation\InstalledApps\Totally Integrated Automation Portal V21INSTALLPATH - Binary path:
C:\Program Files\Siemens\Automation\Portal V21\PublicAPI\V21\net48\ - Manifest schemas:
C:\Program Files\Siemens\Automation\Portal V21\PublicAPI\V21\Schemas\
- 注册表项: → 值
HKLM\SOFTWARE\Siemens\Automation\InstalledApps\Totally Integrated Automation Portal V21INSTALLPATH - 二进制文件路径:
C:\Program Files\Siemens\Automation\Portal V21\PublicAPI\V21\net48\ - 清单架构:
C:\Program Files\Siemens\Automation\Portal V21\PublicAPI\V21\Schemas\
Resolver pattern
解析器模式
When using the approach, register the event before any Openness type is
referenced. This includes method parameters, return types, and class properties — not just
method bodies. A correctly configured binding is an alternative.
AssemblyResolveapp.configRecommended pattern: register in a static constructor of , then move all Openness
code to a separate class so the resolver is active before those classes are loaded.
Programcsharp
internal static class Program
{
// Register resolver at earliest possible point
static Program()
{
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
}
public static void Main()
{
// All Openness code must be in a separate class
var app = new OpennessApp();
app.Run();
}
private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
{
// Read install path from registry (recommended) or hardcode for simple tools
string opennessFolder = GetOpennessInstallPath(); // implement per project
AssemblyName requestedName = new AssemblyName(args.Name);
string filePath = Path.Combine(opennessFolder,
string.Concat(requestedName.Name, ".dll"));
if (!requestedName.Name.StartsWith("Siemens.Engineering.") ||
!File.Exists(filePath))
return null;
Assembly loaded = Assembly.LoadFrom(filePath);
if (requestedName.FullName != loaded.GetName().FullName)
throw new FileNotFoundException(
"TIA Portal Openness version does not match", filePath);
return loaded;
}
}Key rules:
- (
Copy Local: False) must be set for every<Private>False</Private>assembly reference.Siemens.Engineering - V21 uses modular DLLs: is always needed; add
Base.dll,Step7.dll,WinCC.dll, etc. per task. The resolver handles all of them automatically because it matches any name starting withStartdrive.dll.Siemens.Engineering. - The recommended approach reads the install path from the registry key
(value
HKLM\SOFTWARE\Siemens\Automation\InstalledApps\Totally Integrated Automation Portal V21) rather than hardcoding it.INSTALLPATH
Registry-based path discovery:
csharp
private static string GetOpennessInstallPath()
{
using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Siemens\Automation\InstalledApps\Totally Integrated Automation Portal V21"))
{
string installPath = key?.GetValue("INSTALLPATH") as string;
if (string.IsNullOrEmpty(installPath))
throw new FileNotFoundException("TIA Portal V21 installation not found in registry.");
return Path.Combine(installPath, @"PublicAPI\V21\net48");
}
}Alternative — app.config:
For stable installations where the path is known at build time, an file with
/ entries is a simpler option that requires no code.
Use the event for tools that need to discover the install path at runtime.
app.config<assemblyBinding><codeBase>AssemblyResolve使用方法时,需在引用任何Openness类型前注册该事件。这包括方法参数、返回类型和类属性——不仅仅是方法体。配置正确的绑定是替代方案。
AssemblyResolveapp.config推荐模式:在的静态构造函数中注册,然后将所有Openness代码移至单独类中,确保解析器在这些类加载前已激活。
Programcsharp
internal static class Program
{
// 尽早注册解析器
static Program()
{
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
}
public static void Main()
{
// 所有Openness代码必须放在单独类中
var app = new OpennessApp();
app.Run();
}
private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
{
// 从注册表读取安装路径(推荐),或为简单工具硬编码路径
string opennessFolder = GetOpennessInstallPath(); // 根据项目实现
AssemblyName requestedName = new AssemblyName(args.Name);
string filePath = Path.Combine(opennessFolder,
string.Concat(requestedName.Name, ".dll"));
if (!requestedName.Name.StartsWith("Siemens.Engineering.") ||
!File.Exists(filePath))
return null;
Assembly loaded = Assembly.LoadFrom(filePath);
if (requestedName.FullName != loaded.GetName().FullName)
throw new FileNotFoundException(
"TIA Portal Openness版本不匹配", filePath);
return loaded;
}
}核心规则:
- 所有程序集引用必须设置
Siemens.Engineering(Copy Local: False)。<Private>False</Private> - V21使用模块化DLL:是必备项;根据任务需求添加
Base.dll、Step7.dll、WinCC.dll等。解析器会自动处理所有这些DLL,因为它匹配任何以Startdrive.dll开头的名称。Siemens.Engineering. - 推荐方法从注册表项(值
HKLM\SOFTWARE\Siemens\Automation\InstalledApps\Totally Integrated Automation Portal V21)读取安装路径,而非硬编码。INSTALLPATH
基于注册表的路径发现:
csharp
private static string GetOpennessInstallPath()
{
using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Siemens\Automation\InstalledApps\Totally Integrated Automation Portal V21"))
{
string installPath = key?.GetValue("INSTALLPATH") as string;
if (string.IsNullOrEmpty(installPath))
throw new FileNotFoundException("注册表中未找到TIA Portal V21安装信息。");
return Path.Combine(installPath, @"PublicAPI\V21\net48");
}
}替代方案——app.config:
对于构建时已知路径的稳定安装环境,带有/条目的文件是无需编写代码的更简单选项。对于需要在运行时发现安装路径的工具,使用事件。
<assemblyBinding><codeBase>app.configAssemblyResolveTiaPortal instantiation
TiaPortal实例化
Always use a statement so the session is disposed on exit or exception:
usingcsharp
internal class OpennessApp
{
public void Run()
{
using (TiaPortal tiaPortal = new TiaPortal(TiaPortalMode.WithUserInterface))
{
// All Openness work goes here
}
// TIA Portal is disposed (not necessarily closed) after this point
}
}Modes:
- — starts a new TIA Portal instance with a visible GUI
TiaPortalMode.WithUserInterface - — starts a new headless instance, suitable for automation pipelines
TiaPortalMode.WithoutUserInterface
Attaching to a running instance:
csharp
// Attach to the first running TIA Portal process of this Openness version
TiaPortal tiaPortal = TiaPortal.GetProcesses().First().Attach();Use when TIA Portal is already open and you do not want to start a new
instance. Returns only processes from the same Openness version as the loaded assembly.
GetProcesses()Dispose vs. close:
- If started headless and no other Openness client is attached, closes TIA Portal.
Dispose() - If started with GUI or other clients are attached, only disconnects.
Dispose() - After disposal, the connection is no longer valid. A later API call after the TIA Portal
process is closed externally throws .
NonRecoverableException
始终使用语句,确保会话在退出或发生异常时被释放:
usingcsharp
internal class OpennessApp
{
public void Run()
{
using (TiaPortal tiaPortal = new TiaPortal(TiaPortalMode.WithUserInterface))
{
// 所有Openness操作在此执行
}
// 此步骤后TIA Portal被释放(不一定关闭)
}
}模式:
- —— 启动带有可见GUI的新TIA Portal实例
TiaPortalMode.WithUserInterface - —— 启动无界面实例,适用于自动化流水线
TiaPortalMode.WithoutUserInterface
附加到运行中的实例:
csharp
// 附加到当前Openness版本的第一个运行中TIA Portal进程
TiaPortal tiaPortal = TiaPortal.GetProcesses().First().Attach();当TIA Portal已打开且不想启动新实例时,使用。仅返回与已加载程序集同版本的Openness进程。
GetProcesses()释放与关闭的区别:
- 如果以无界面模式启动且无其他Openness客户端附加,会关闭TIA Portal。
Dispose() - 如果以GUI模式启动或有其他客户端附加,仅断开连接。
Dispose() - 释放后,连接不再有效。TIA Portal进程被外部关闭后,后续API调用会引发。
NonRecoverableException
Service providers — GetService<T>()
GetService<T>()服务提供器——GetService<T>()
GetService<T>()V21 uses a service-provider pattern for UI interactions. Call on the
instance to obtain a service. Available services depend on the runtime context.
GetService<T>()TiaPortalV21使用服务提供器模式处理UI交互。在实例上调用获取服务。可用服务取决于运行时上下文。
TiaPortalGetService<T>()Add-In runtime services
插件运行时服务
These services are available only when code runs inside a TIA Portal Add-In:
| Service type | Namespace | Purpose |
|---|---|---|
| | Display notification/confirmation dialogs in TIA Portal |
| | Display a progress bar; check |
| | Log messages to TIA Portal's Inspector window (General Info tab) |
csharp
// MessageBoxProvider — notification and confirmation dialogs
var msgBox = tiaPortal.GetService<MessageBoxProvider>();
msgBox?.ShowNotification(NotificationIcon.Information, "Title", "Message text");
msgBox?.ShowNotification(NotificationIcon.Warning, "Title", "Message", "Detail text");
// Confirmation dialog — defaultChoice is the pre-selected button; return value is user's choice
ConfirmationResult result = msgBox.ShowConfirmation(
ConfirmationIcon.General, "Title", "Proceed?",
ConfirmationChoices.Yes | ConfirmationChoices.No, ConfirmationResult.Yes);
if (result == ConfirmationResult.No) return;
// ProgressProvider — progress bar with cancellation
var progress = tiaPortal.GetService<ProgressProvider>();
progress?.Update("Step description", "Detail text");
if (progress?.IsCancelRequested == true)
{
// User requested cancellation — clean up and return
}
// FeedbackProvider — log to Inspector window (General Info tab)
var feedback = tiaPortal.GetService<FeedbackProvider>();
feedback?.Log(NotificationIcon.Information, "Operation completed successfully.");
feedback?.Log(NotificationIcon.Warning, "Skipped 3 items due to missing data.");Important: In Add-In status callbacks (the delegate passed to
), returns . Only use services in action
callbacks where COM access is fully available.
OnUpdateStatusAddActionItemGetService<T>()null这些服务仅在代码运行于TIA Portal插件内部时可用:
| 服务类型 | 命名空间 | 用途 |
|---|---|---|
| | 在TIA Portal中显示通知/确认对话框 |
| | 显示进度条;检查 |
| | 将消息记录到TIA Portal的检查器窗口(常规信息标签页) |
csharp
// MessageBoxProvider —— 通知与确认对话框
var msgBox = tiaPortal.GetService<MessageBoxProvider>();
msgBox?.ShowNotification(NotificationIcon.Information, "标题", "消息文本");
msgBox?.ShowNotification(NotificationIcon.Warning, "标题", "消息", "详细文本");
// 确认对话框 —— defaultChoice是预选中的按钮;返回值为用户选择
ConfirmationResult result = msgBox.ShowConfirmation(
ConfirmationIcon.General, "标题", "是否继续?",
ConfirmationChoices.Yes | ConfirmationChoices.No, ConfirmationResult.Yes);
if (result == ConfirmationResult.No) return;
// ProgressProvider —— 带取消功能的进度条
var progress = tiaPortal.GetService<ProgressProvider>();
progress?.Update("步骤描述", "详细文本");
if (progress?.IsCancelRequested == true)
{
// 用户请求取消——清理并返回
}
// FeedbackProvider —— 记录到检查器窗口(常规信息标签页)
var feedback = tiaPortal.GetService<FeedbackProvider>();
feedback?.Log(NotificationIcon.Information, "操作成功完成。");
feedback?.Log(NotificationIcon.Warning, "因数据缺失跳过3项。");重要提示: 在插件状态回调(传递给的委托)中,返回。仅在COM访问完全可用的操作回调中使用服务。
AddActionItemOnUpdateStatusGetService<T>()nullEvent handlers
事件处理程序
Four events are available on . Always unsubscribe in a block.
TiaPortalfinallyTiaPortalfinallyDisposed
Disposed
Fires when TIA Portal closes while the Openness client is still connected.
csharp
tiaPortal.Disposed += OnDisposed;
try
{
// ... work ...
}
finally
{
tiaPortal.Disposed -= OnDisposed;
}
private static void OnDisposed(object sender, EventArgs e)
{
// TIA Portal was closed externally — clean up and exit
}当Openness客户端仍连接时TIA Portal关闭,触发此事件。
csharp
tiaPortal.Disposed += OnDisposed;
try
{
// ... 执行操作 ...
}
finally
{
tiaPortal.Disposed -= OnDisposed;
}
private static void OnDisposed(object sender, EventArgs e)
{
// TIA Portal被外部关闭——清理并退出
}Notification
Notification
Fires for informational messages that require only an acknowledgment (OK).
csharp
tiaPortal.Notification += OnNotification;
try { /* ... */ }
finally { tiaPortal.Notification -= OnNotification; }
private static void OnNotification(object sender, NotificationEventArgs e)
{
Console.WriteLine($"[TIA Notification] {e.Text}");
// No response required — notification is auto-acknowledged
}当需要仅确认(OK)的信息类消息出现时触发。
csharp
tiaPortal.Notification += OnNotification;
try { /* ... */ }
finally { tiaPortal.Notification -= OnNotification; }
private static void OnNotification(object sender, NotificationEventArgs e)
{
Console.WriteLine($"[TIA通知] {e.Text}");
// 无需响应——通知会自动确认
}Confirmation
Confirmation
Fires for dialogs that require a decision. Must set to one of:
, , or . Any other value throws an exception.
e.Result"Yes""YesToAll""No"Auto-confirm pattern (most common in automation):
csharp
tiaPortal.Confirmation += OnConfirmation;
try { /* ... */ }
finally { tiaPortal.Confirmation -= OnConfirmation; }
private static void OnConfirmation(object sender, ConfirmationEventArgs e)
{
e.Result = "Yes";
}当需要做出决策的对话框出现时触发。必须将设置为以下值之一:、或。任何其他值都会引发异常。
e.Result"Yes""YesToAll""No"自动确认模式(自动化中最常用):
csharp
tiaPortal.Confirmation += OnConfirmation;
try { /* ... */ }
finally { tiaPortal.Confirmation -= OnConfirmation; }
private static void OnConfirmation(object sender, ConfirmationEventArgs e)
{
e.Result = "Yes";
}Authentication (V17+)
Authentication(V17+)
Fires when opening a UMAC-protected project. Use to specify the authentication method
instead of passing credentials via . Only fires for protected projects.
UmacDelegatecsharp
tiaPortal.Authentication += OnAuthentication;
try { /* open project ... */ }
finally { tiaPortal.Authentication -= OnAuthentication; }
private static void OnAuthentication(object sender, AuthenticationEventArgs e)
{
// Choose one of: DesktopSso, Anonymous, Interactive, Credentials
e.AuthenticationTypeProvider = AuthenticationTypeProvider.DesktopSso;
// For Credentials mode, credentials are supplied separately via UmacDelegate
} | Behaviour |
|---|---|
| Signs in with the current Windows user — no password prompt |
| Uses the anonymous user account — no password prompt |
| Shows TIA Portal login dialog to the user |
| Reads credentials from the supplied |
打开受UMAC保护的项目时触发。用于指定身份验证方法,而非通过传递凭据。仅在打开受保护项目时触发。
UmacDelegatecsharp
tiaPortal.Authentication += OnAuthentication;
try { /* 打开项目 ... */ }
finally { tiaPortal.Authentication -= OnAuthentication; }
private static void OnAuthentication(object sender, AuthenticationEventArgs e)
{
// 选择以下选项之一:DesktopSso、Anonymous、Interactive、Credentials
e.AuthenticationTypeProvider = AuthenticationTypeProvider.DesktopSso;
// 若使用Credentials模式,需通过UmacDelegate单独提供凭据
} | 行为 |
|---|---|
| 使用当前Windows用户登录——无需密码提示 |
| 使用匿名用户账户——无需密码提示 |
| 向用户显示TIA Portal登录对话框 |
| 从提供的 |
Exclusive access
独占访问
Highly recommended for all non-trivial operations. Signals TIA Portal that a controlled
activity is in progress and displays a dialog to the user.
csharp
using (ExclusiveAccess exclusiveAccess = tiaPortal.ExclusiveAccess("Generating project"))
{
// All Openness operations here run under exclusive access
// Optionally update the displayed message during long operations
exclusiveAccess.Text = "Compiling software";
// ...
exclusiveAccess.Text = "Downloading to PLC";
}
// Exclusive access is released on disposeRules:
- Only one can exist at a time — a second attempt throws a recoverable exception while the first is still active.
ExclusiveAccess - Setting or
exclusiveAccess.Text = string.Emptyclears the displayed message.null
强烈建议所有非 trivial 操作使用此功能。向TIA Portal发出信号,表示正在进行受控活动,并向用户显示对话框。
csharp
using (ExclusiveAccess exclusiveAccess = tiaPortal.ExclusiveAccess("生成项目"))
{
// 所有Openness操作在此独占访问范围内执行
// 长操作期间可选择更新显示的消息
exclusiveAccess.Text = "编译软件";
// ...
exclusiveAccess.Text = "下载至PLC";
}
// 释放时独占访问权限被解除规则:
- 同一时间只能存在一个——第一个仍活跃时,第二次尝试会引发可恢复异常。
ExclusiveAccess - 设置或
exclusiveAccess.Text = string.Empty会清除显示的消息。null
Transactions
事务
Group multiple modifications into a single undo unit. Requires an active .
ExclusiveAccesscsharp
using (ExclusiveAccess exclusiveAccess = tiaPortal.ExclusiveAccess("Bulk edit"))
{
using (Transaction transaction = exclusiveAccess.Transaction(project, "Create blocks"))
{
// Perform all modifications
project.DeviceGroups.Create("Line_1");
project.DeviceGroups.Create("Line_2");
// MANDATORY: call CommitOnDispose() to persist changes
// If this line is never reached, the transaction is rolled back
transaction.CommitOnDispose();
}
}Rollback rules — critical:
- If is never called → rolled back on dispose.
CommitOnDispose() - If an exception occurs at any point before the transaction is disposed → rolled back,
including when was already requested or the exception was caught.
CommitOnDispose() - After an , a later
EngineeringTargetInvocationExceptionrequest can itself raise a recoverable exception; checkCommitOnDispose()and do not assume persistence.CanCommit
Not allowed inside a transaction:
Compile, go online/offline, ProjectText import/export, opening or closing a global library,
project create/open/open-with-upgrade/save/save-as/close, and changing a TIA Portal setting.
These calls raise a recoverable exception while a transaction is active.
将多个修改分组为单个撤销单元。需要激活的。
ExclusiveAccesscsharp
using (ExclusiveAccess exclusiveAccess = tiaPortal.ExclusiveAccess("批量编辑"))
{
using (Transaction transaction = exclusiveAccess.Transaction(project, "创建块"))
{
// 执行所有修改操作
project.DeviceGroups.Create("Line_1");
project.DeviceGroups.Create("Line_2");
// 必须:调用CommitOnDispose()以保存更改
// 若未执行此步骤,事务会在释放时回滚
transaction.CommitOnDispose();
}
}回滚规则——关键:
- 若从未调用→ 释放时回滚。
CommitOnDispose() - 事务释放前任何点发生异常 → 回滚,即使已调用或异常已被捕获。
CommitOnDispose() - 发生后,后续的
EngineeringTargetInvocationException请求本身可能引发可恢复异常;需检查CommitOnDispose(),不要假设更改已持久化。CanCommit
事务内禁止操作:
编译、上线/离线、ProjectText导入/导出、打开或关闭全局库、项目创建/打开/升级打开/保存/另存为/关闭、更改TIA Portal设置。事务活跃时调用这些操作会引发可恢复异常。
Destructive-operation safety
破坏性操作安全规范
These rules are mandatory for generated C# Openness code:
- Never bare . Any destructive operation must be inside an active
.Delete()scope and aExclusiveAccesswhen the API permits transactions.Transaction - Use blocks for
using,ExclusiveAccess,Transaction, and other disposable Openness objects so rollback and release behavior is explicit. Close projects explicitly according to lifecycle ownership;TiaPortalis not anProjectobject.IDisposable - Call only after every validation and mutation in the transaction has succeeded.
transaction.CommitOnDispose() - Run or request a after generated block, tag, hardware, or HMI changes. Do not present generated project changes as deployable until that check passes.
compile_check - If an API refuses to run inside a transaction, state that limitation explicitly,
use the narrowest possible scope, and require a preview or user confirmation before the destructive call.
ExclusiveAccess
以下规则对生成的C# Openness代码是强制性的:
- 禁止直接调用。任何破坏性操作必须在活跃的
.Delete()范围内执行,且API允许时需包含在ExclusiveAccess中。Transaction - 对、
ExclusiveAccess、Transaction及其他可释放的Openness对象使用TiaPortal块,确保回滚和释放行为明确。根据生命周期所有权显式关闭项目;using不是Project对象。IDisposable - 仅在事务中的所有验证和修改操作成功后,才调用。
transaction.CommitOnDispose() - 生成块、标签、硬件或HMI更改后,运行或请求。在检查通过前,不要将生成的项目更改标记为可部署。
compile_check - 若API拒绝在事务内运行,需明确说明该限制,使用尽可能窄的范围,并在执行破坏性调用前要求预览或用户确认。
ExclusiveAccess
Exception handling
异常处理
Two top-level categories:
| Category | Base type | Behaviour |
|---|---|---|
| Recoverable | | API call failed; session remains valid |
| Non-recoverable | | TIA Portal closed; restart required |
Recoverable subtypes:
| Type | Typical cause |
|---|---|
| Missing access rights |
| Object no longer exists (e.g. deleted) |
| Attribute or operation not available on this object |
| General failure despite a valid API call |
| Runtime error, e.g. invalid cast |
| Insufficient resources in TIA Portal instance |
| Operation cancelled by the user (e.g. import dialog) |
| Exception thrown inside a caller-supplied delegate |
| Project requires TIA Portal products/packages not installed (V18+) |
Recommended catch order:
csharp
try
{
// Openness work
}
catch (EngineeringSecurityException ex)
{
Console.WriteLine($"Access denied: {ex.Message}");
}
catch (EngineeringObjectDisposedException ex)
{
Console.WriteLine($"Object disposed: {ex.Message}");
}
catch (EngineeringNotSupportedException ex)
{
Console.WriteLine($"Not supported: {ex.MessageData.Text}");
foreach (ExceptionMessageData detail in ex.DetailMessageData)
Console.WriteLine($" Detail: {detail.Text}");
}
catch (MissingProductsException ex)
{
Console.WriteLine($"Missing products: {ex.Message}");
}
catch (EngineeringTargetInvocationException)
{
throw; // Do not swallow — rethrow for caller to handle
}
catch (EngineeringException)
{
throw; // Do not swallow general engineering exceptions
}
catch (NonRecoverableException ex)
{
Console.WriteLine($"Fatal — TIA Portal closed: {ex.Message}");
// Must restart TIA Portal; the session is gone
}分为两大类:
| 类别 | 基类 | 行为 |
|---|---|---|
| 可恢复 | | API调用失败;会话仍有效 |
| 不可恢复 | | TIA Portal已关闭;需重启 |
可恢复子类:
| 类型 | 典型原因 |
|---|---|
| 缺少访问权限 |
| 对象已不存在(如已删除) |
| 对象不支持该属性或操作 |
| API调用格式正确但执行失败 |
| 运行时错误,如无效转换 |
| TIA Portal实例资源不足 |
| 用户取消操作(如导入对话框) |
| 调用者提供的委托内部引发异常 |
| 项目需要的TIA Portal产品/包未安装(V18+) |
推荐捕获顺序:
csharp
try
{
// Openness操作
}
catch (EngineeringSecurityException ex)
{
Console.WriteLine($"访问被拒绝:{ex.Message}");
}
catch (EngineeringObjectDisposedException ex)
{
Console.WriteLine($"对象已释放:{ex.Message}");
}
catch (EngineeringNotSupportedException ex)
{
Console.WriteLine($"不支持该操作:{ex.MessageData.Text}");
foreach (ExceptionMessageData detail in ex.DetailMessageData)
Console.WriteLine($" 详情:{detail.Text}");
}
catch (MissingProductsException ex)
{
Console.WriteLine($"缺失产品:{ex.Message}");
}
catch (EngineeringTargetInvocationException)
{
throw; // 不要吞掉——重新抛出由调用者处理
}
catch (EngineeringException)
{
throw; // 不要吞掉通用工程异常
}
catch (NonRecoverableException ex)
{
Console.WriteLine($"致命错误——TIA Portal已关闭:{ex.Message}");
// 必须重启TIA Portal;会话已失效
}Project open mode
项目打开模式
When opening multiple projects or working in multiuser environments:
csharp
// Primary — visible in project navigation, full read-write access
Project primary = tiaPortal.Projects.Open(
new FileInfo(path), umacDelegate, ProjectOpenMode.Primary);
// Secondary — hidden from UI, always read-only regardless of user rights
Project secondary = tiaPortal.Projects.Open(
new FileInfo(path), null, ProjectOpenMode.Secondary);
bool isPrimary = secondary.IsPrimary; // falseRules:
- Only one primary project per TIA Portal instance.
- Secondary projects do not need a primary project to be open first.
- A user with write rights to a UMAC-protected project still gets read-only access when opening it as secondary.
打开多个项目或在多用户环境中工作时:
csharp
// 主项目——在项目导航中可见,拥有完整读写权限
Project primary = tiaPortal.Projects.Open(
new FileInfo(path), umacDelegate, ProjectOpenMode.Primary);
// 副项目——对UI隐藏,无论用户权限如何始终为只读
Project secondary = tiaPortal.Projects.Open(
new FileInfo(path), null, ProjectOpenMode.Secondary);
bool isPrimary = secondary.IsPrimary; // false规则:
- 每个TIA Portal实例只能有一个主项目。
- 副项目无需先打开主项目即可打开。
- 拥有受UMAC保护项目写入权限的用户,以副项目模式打开时仍只能获得只读权限。
Object model contracts
对象模型约定
Composition methods
组合方法
Most engineering objects are accessed through compositions. Available methods:
| Method | Behaviour |
|---|---|
| Creates and adds a new instance. Signature varies per composition. |
| Finds by identifier. Non-recursive — searches current level only. |
| Used implicitly in |
| Returns |
| Returns |
| Available on compositions that support import. |
| Removes and deletes the instance. |
Not all methods are available on every composition — check domain skills.
大多数工程对象通过组合访问。可用方法:
| 方法 | 行为 |
|---|---|
| 创建并添加新实例。签名因组合而异。 |
| 通过标识符查找。非递归——仅搜索当前层级。 |
| 在 |
| 返回 |
| 返回对象在组合中的 |
| 支持导入的组合可用。 |
| 移除并删除实例。 |
并非所有方法在每个组合中都可用——请查看领域技能文档。
Object equality
对象相等性
csharp
// Reference equality (same .NET object reference)
bool sameRef = (objA == objB);
// TIA Portal identity equality (same engineering object, possibly different references)
bool sameObj = System.Object.Equals(objA, objB);Use when comparing objects retrieved through different navigation
paths that may represent the same underlying engineering object.
System.Object.Equals()csharp
// 引用相等(同一.NET对象引用)
bool sameRef = (objA == objB);
// TIA Portal标识相等(同一工程对象,可能是不同引用)
bool sameObj = System.Object.Equals(objA, objB);当比较通过不同导航路径获取的、可能代表同一底层工程对象的实例时,使用。
System.Object.Equals()DirectoryInfo / FileInfo — absolute paths only
DirectoryInfo / FileInfo —— 仅支持绝对路径
All and instances passed to Openness must use absolute paths.
Relative paths cause an exception at runtime.
DirectoryInfoFileInfocsharp
// Correct
var dir = new DirectoryInfo(@"C:\Projects\MyProject\Export");
// Wrong — will throw
var dir = new DirectoryInfo(@"Export");传递给Openness的所有和实例必须使用绝对路径。相对路径会在运行时引发异常。
DirectoryInfoFileInfocsharp
// 正确
var dir = new DirectoryInfo(@"C:\Projects\MyProject\Export");
// 错误——会引发异常
var dir = new DirectoryInfo(@"Export");Bulk attribute access
批量属性访问
Useful for dynamic tooling or when setting multiple attributes efficiently on HW objects.
适用于动态工具或高效设置HW对象的多个属性。
Read all attributes
读取所有属性
csharp
// Get names of all available attributes
IList<EngineeringAttributeInfo> infos =
((IEngineeringObject)deviceItem).GetAttributeInfos();
// Read all readable attributes in one call
IList<string> names = infos.Select(i => i.Name).ToList();
IList<object> values = ((IEngineeringObject)deviceItem).GetAttributes(names);csharp
// 获取所有可用属性的名称
IList<EngineeringAttributeInfo> infos =
((IEngineeringObject)deviceItem).GetAttributeInfos();
// 一次性读取所有可读属性
IList<string> names = infos.Select(i => i.Name).ToList();
IList<object> values = ((IEngineeringObject)deviceItem).GetAttributes(names);Filtered read by access mode
按访问模式过滤读取
csharp
// AttributeAccessOptions: None, ReadOnly, WriteOnly, ReadWrite
IReadOnlyList<KeyValuePair<string, object>> readableAttrs =
deviceItem.GetAttributes(AttributeAccessOptions.ReadOnly);csharp
// AttributeAccessOptions: None、ReadOnly、WriteOnly、ReadWrite
IReadOnlyList<KeyValuePair<string, object>> readableAttrs =
deviceItem.GetAttributes(AttributeAccessOptions.ReadOnly);Bulk write (HW objects only — provides callback)
批量写入(仅HW对象——提供回调)
csharp
var pairs = new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("Name", "NewModuleName"),
new KeyValuePair<string, object>("Comment", "Auto-generated")
};
// Overload with callback fires after each attribute is set
deviceItem.SetAttributes(pairs, (name, val, ex) =>
{
if (ex != null)
Console.WriteLine($"Failed to set {name}: {ex.Message}");
});
// Overload without callback — for non-HW objects
((IEngineeringObject)someObject).SetAttributes(pairs);csharp
var pairs = new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("Name", "NewModuleName"),
new KeyValuePair<string, object>("Comment", "自动生成")
};
// 带回调的重载会在每个属性设置后触发
deviceItem.SetAttributes(pairs, (name, val, ex) =>
{
if (ex != null)
Console.WriteLine($"设置{name}失败:{ex.Message}");
});
// 不带回调的重载——适用于非HW对象
((IEngineeringObject)someObject).SetAttributes(pairs);