tia-csharp-common

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TIA 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
Siemens.Engineering.dll
. Every project needs
Siemens.Engineering.Base.dll
; add domain DLLs as required. Referencing the wrong DLL (or omitting one) causes
TypeLoadException
at runtime.
Full mapping: See
references/assembly-namespace-map.md
for the V21 namespace → DLL → domain skill table, cross-assembly warnings, and csproj patterns.
V21将API拆分到多个DLL中,而非单一的
Siemens.Engineering.dll
。每个项目都需要
Siemens.Engineering.Base.dll
;可根据需求添加领域相关的DLL。引用错误的DLL(或遗漏必要DLL)会在运行时引发
TypeLoadException
完整映射: 请查看
references/assembly-namespace-map.md
获取V21的命名空间→DLL→领域技能对照表、跨程序集警告以及csproj配置模板。

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 providers
Siemens.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, PlcForceTable
Siemens.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 themes
Siemens.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, UMAC
Siemens.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、PlcForceTable
Siemens.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; // 驱动加密、UMAC
Siemens.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:
    HKLM\SOFTWARE\Siemens\Automation\InstalledApps\Totally Integrated Automation Portal V21
    → value
    INSTALLPATH
  • 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 V21
    → 值
    INSTALLPATH
  • 二进制文件路径:
    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
AssemblyResolve
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
app.config
binding is an alternative.
Recommended pattern: register in a static constructor of
Program
, then move all Openness code to a separate class so the resolver is active before those classes are loaded.
csharp
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
    (
    <Private>False</Private>
    ) must be set for every
    Siemens.Engineering
    assembly reference.
  • V21 uses modular DLLs:
    Base.dll
    is always needed; add
    Step7.dll
    ,
    WinCC.dll
    ,
    Startdrive.dll
    , etc. per task. The resolver handles all of them automatically because it matches any name starting with
    Siemens.Engineering.
    .
  • The recommended approach reads the install path from the registry key
    HKLM\SOFTWARE\Siemens\Automation\InstalledApps\Totally Integrated Automation Portal V21
    (value
    INSTALLPATH
    ) rather than hardcoding it.
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
app.config
file with
<assemblyBinding>
/
<codeBase>
entries is a simpler option that requires no code. Use the
AssemblyResolve
event for tools that need to discover the install path at runtime.

使用
AssemblyResolve
方法时,需在引用任何Openness类型前注册该事件。这包括方法参数、返回类型和类属性——不仅仅是方法体。配置正确的
app.config
绑定是替代方案。
推荐模式:在
Program
的静态构造函数中注册,然后将所有Openness代码移至单独类中,确保解析器在这些类加载前已激活。
csharp
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
    Startdrive.dll
    等。解析器会自动处理所有这些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.config
文件是无需编写代码的更简单选项。对于需要在运行时发现安装路径的工具,使用
AssemblyResolve
事件。

TiaPortal instantiation

TiaPortal实例化

Always use a
using
statement so the session is disposed on exit or exception:
csharp
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:
  • TiaPortalMode.WithUserInterface
    — starts a new TIA Portal instance with a visible GUI
  • TiaPortalMode.WithoutUserInterface
    — starts a new headless instance, suitable for automation pipelines
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
GetProcesses()
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.
Dispose vs. close:
  • If started headless and no other Openness client is attached,
    Dispose()
    closes TIA Portal.
  • If started with GUI or other clients are attached,
    Dispose()
    only disconnects.
  • After disposal, the connection is no longer valid. A later API call after the TIA Portal process is closed externally throws
    NonRecoverableException
    .

始终使用
using
语句,确保会话在退出或发生异常时被释放:
csharp
internal class OpennessApp
{
    public void Run()
    {
        using (TiaPortal tiaPortal = new TiaPortal(TiaPortalMode.WithUserInterface))
        {
            // 所有Openness操作在此执行
        }
        // 此步骤后TIA Portal被释放(不一定关闭)
    }
}
模式:
  • TiaPortalMode.WithUserInterface
    —— 启动带有可见GUI的新TIA Portal实例
  • TiaPortalMode.WithoutUserInterface
    —— 启动无界面实例,适用于自动化流水线
附加到运行中的实例:
csharp
// 附加到当前Openness版本的第一个运行中TIA Portal进程
TiaPortal tiaPortal = TiaPortal.GetProcesses().First().Attach();
当TIA Portal已打开且不想启动新实例时,使用
GetProcesses()
。仅返回与已加载程序集同版本的Openness进程。
释放与关闭的区别:
  • 如果以无界面模式启动且无其他Openness客户端附加,
    Dispose()
    会关闭TIA Portal。
  • 如果以GUI模式启动或有其他客户端附加,
    Dispose()
    仅断开连接。
  • 释放后,连接不再有效。TIA Portal进程被外部关闭后,后续API调用会引发
    NonRecoverableException

Service providers —
GetService<T>()

服务提供器——
GetService<T>()

V21 uses a service-provider pattern for UI interactions. Call
GetService<T>()
on the
TiaPortal
instance to obtain a service. Available services depend on the runtime context.
V21使用服务提供器模式处理UI交互。在
TiaPortal
实例上调用
GetService<T>()
获取服务。可用服务取决于运行时上下文。

Add-In runtime services

插件运行时服务

These services are available only when code runs inside a TIA Portal Add-In:
Service typeNamespacePurpose
MessageBoxProvider
Siemens.Engineering.AddIn
Display notification/confirmation dialogs in TIA Portal
ProgressProvider
Siemens.Engineering.AddIn
Display a progress bar; check
IsCancelRequested
for cancellation
FeedbackProvider
Siemens.Engineering.AddIn
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
OnUpdateStatus
delegate passed to
AddActionItem
),
GetService<T>()
returns
null
. Only use services in action callbacks where COM access is fully available.

这些服务仅在代码运行于TIA Portal插件内部时可用:
服务类型命名空间用途
MessageBoxProvider
Siemens.Engineering.AddIn
在TIA Portal中显示通知/确认对话框
ProgressProvider
Siemens.Engineering.AddIn
显示进度条;检查
IsCancelRequested
判断是否取消
FeedbackProvider
Siemens.Engineering.AddIn
将消息记录到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项。");
重要提示: 在插件状态回调(传递给
AddActionItem
OnUpdateStatus
委托)中,
GetService<T>()
返回
null
。仅在COM访问完全可用的操作回调中使用服务。

Event handlers

事件处理程序

Four events are available on
TiaPortal
. Always unsubscribe in a
finally
block.
TiaPortal
提供四个事件。务必在
finally
块中取消订阅。

Disposed

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
e.Result
to one of:
"Yes"
,
"YesToAll"
, or
"No"
. Any other value throws an exception.
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
UmacDelegate
. Only fires for protected projects.
csharp
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
}
AuthenticationTypeProvider
Behaviour
DesktopSso
Signs in with the current Windows user — no password prompt
Anonymous
Uses the anonymous user account — no password prompt
Interactive
Shows TIA Portal login dialog to the user
Credentials
Reads credentials from the supplied
UmacDelegate

打开受UMAC保护的项目时触发。用于指定身份验证方法,而非通过
UmacDelegate
传递凭据。仅在打开受保护项目时触发。
csharp
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单独提供凭据
}
AuthenticationTypeProvider
行为
DesktopSso
使用当前Windows用户登录——无需密码提示
Anonymous
使用匿名用户账户——无需密码提示
Interactive
向用户显示TIA Portal登录对话框
Credentials
从提供的
UmacDelegate
读取凭据

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 dispose
Rules:
  • Only one
    ExclusiveAccess
    can exist at a time — a second attempt throws a recoverable exception while the first is still active.
  • Setting
    exclusiveAccess.Text = string.Empty
    or
    null
    clears the displayed message.

强烈建议所有非 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
ExclusiveAccess
.
csharp
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
    CommitOnDispose()
    is never called → rolled back on dispose.
  • If an exception occurs at any point before the transaction is disposed → rolled back, including when
    CommitOnDispose()
    was already requested or the exception was caught.
  • After an
    EngineeringTargetInvocationException
    , a later
    CommitOnDispose()
    request can itself raise a recoverable exception; check
    CanCommit
    and do not assume persistence.
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.

将多个修改分组为单个撤销单元。需要激活的
ExclusiveAccess
csharp
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
    .Delete()
    . Any destructive operation must be inside an active
    ExclusiveAccess
    scope and a
    Transaction
    when the API permits transactions.
  • Use
    using
    blocks for
    ExclusiveAccess
    ,
    Transaction
    ,
    TiaPortal
    , and other disposable Openness objects so rollback and release behavior is explicit. Close projects explicitly according to lifecycle ownership;
    Project
    is not an
    IDisposable
    object.
  • Call
    transaction.CommitOnDispose()
    only after every validation and mutation in the transaction has succeeded.
  • Run or request a
    compile_check
    after generated block, tag, hardware, or HMI changes. Do not present generated project changes as deployable until that check passes.
  • If an API refuses to run inside a transaction, state that limitation explicitly, use the narrowest possible
    ExclusiveAccess
    scope, and require a preview or user confirmation before the destructive call.

以下规则对生成的C# Openness代码是强制性的:
  • 禁止直接调用
    .Delete()
    。任何破坏性操作必须在活跃的
    ExclusiveAccess
    范围内执行,且API允许时需包含在
    Transaction
    中。
  • ExclusiveAccess
    Transaction
    TiaPortal
    及其他可释放的Openness对象使用
    using
    块,确保回滚和释放行为明确。根据生命周期所有权显式关闭项目;
    Project
    不是
    IDisposable
    对象。
  • 仅在事务中的所有验证和修改操作成功后,才调用
    transaction.CommitOnDispose()
  • 生成块、标签、硬件或HMI更改后,运行或请求
    compile_check
    。在检查通过前,不要将生成的项目更改标记为可部署。
  • 若API拒绝在事务内运行,需明确说明该限制,使用尽可能窄的
    ExclusiveAccess
    范围,并在执行破坏性调用前要求预览或用户确认。

Exception handling

异常处理

Two top-level categories:
CategoryBase typeBehaviour
Recoverable
Siemens.Engineering.EngineeringException
API call failed; session remains valid
Non-recoverable
Siemens.Engineering.NonRecoverableException
TIA Portal closed; restart required
Recoverable subtypes:
TypeTypical cause
EngineeringSecurityException
Missing access rights
EngineeringObjectDisposedException
Object no longer exists (e.g. deleted)
EngineeringNotSupportedException
Attribute or operation not available on this object
EngineeringTargetInvocationException
General failure despite a valid API call
EngineeringRuntimeException
Runtime error, e.g. invalid cast
EngineeringOutOfMemoryException
Insufficient resources in TIA Portal instance
EngineeringUserAbortException
Operation cancelled by the user (e.g. import dialog)
EngineeringDelegateInvocationException
Exception thrown inside a caller-supplied delegate
MissingProductsException
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
}

分为两大类:
类别基类行为
可恢复
Siemens.Engineering.EngineeringException
API调用失败;会话仍有效
不可恢复
Siemens.Engineering.NonRecoverableException
TIA Portal已关闭;需重启
可恢复子类:
类型典型原因
EngineeringSecurityException
缺少访问权限
EngineeringObjectDisposedException
对象已不存在(如已删除)
EngineeringNotSupportedException
对象不支持该属性或操作
EngineeringTargetInvocationException
API调用格式正确但执行失败
EngineeringRuntimeException
运行时错误,如无效转换
EngineeringOutOfMemoryException
TIA Portal实例资源不足
EngineeringUserAbortException
用户取消操作(如导入对话框)
EngineeringDelegateInvocationException
调用者提供的委托内部引发异常
MissingProductsException
项目需要的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; // false
Rules:
  • 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:
MethodBehaviour
Create(id, ...)
Creates and adds a new instance. Signature varies per composition.
Find(id)
Finds by identifier. Non-recursive — searches current level only.
GetEnumerator()
Used implicitly in
foreach
loops.
Contains(obj)
Returns
bool
— checks if object is in the composition.
IndexOf(obj)
Returns
int
index of the object in the composition.
Import(path, ImportOptions)
Available on compositions that support import.
ImportOptions
:
None
or
Overwrite
.
Delete(obj)
Removes and deletes the instance.
Not all methods are available on every composition — check domain skills.
大多数工程对象通过组合访问。可用方法:
方法行为
Create(id, ...)
创建并添加新实例。签名因组合而异。
Find(id)
通过标识符查找。非递归——仅搜索当前层级。
GetEnumerator()
foreach
循环中隐式使用。
Contains(obj)
返回
bool
——检查对象是否在组合中。
IndexOf(obj)
返回对象在组合中的
int
索引。
Import(path, ImportOptions)
支持导入的组合可用。
ImportOptions
None
Overwrite
Delete(obj)
移除并删除实例。
并非所有方法在每个组合中都可用——请查看领域技能文档。

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
System.Object.Equals()
when comparing objects retrieved through different navigation paths that may represent the same underlying engineering object.
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
DirectoryInfo
and
FileInfo
instances passed to Openness must use absolute paths. Relative paths cause an exception at runtime.
csharp
// Correct
var dir = new DirectoryInfo(@"C:\Projects\MyProject\Export");

// Wrong — will throw
var dir = new DirectoryInfo(@"Export");

传递给Openness的所有
DirectoryInfo
FileInfo
实例必须使用绝对路径。相对路径会在运行时引发异常。
csharp
// 正确
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);