You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

西门子TIA Portal V15备份文件被占用问题及替代方案咨询

问题描述

我正在开发一款工具,实现TIA Portal用户点击下载预览窗口的“确认”后,自动备份PLC项目文件夹的功能。目前遇到的问题:

  • 在TIA Portal V17上测试正常,但V15及以下版本会报错:This file is being used by another process, so that process cannot access it
  • 推测原因:西门子从V17开始优化了文件打开模式,使用File_SHAREREAD允许只读访问,而旧版本独占文件锁导致无法复制
现有实现代码
public void Siemens(TempChangeReasonModel UserClickModel, SqlSugar.SqlSugarScope db)
{
    try
    {
        var date = DateTime.Now;
        var programBackupModel = db.Queryable<PlcBackupConfigurationModel>().First();
        if (programBackupModel == null)
        {
            return;
        }
        if (string.IsNullOrWhiteSpace(UserClickModel.mqttRespones.path))
        {
            throw new Exception($"simens not get path");
        }
        var pathIndex = UserClickModel.mqttRespones.path.IndexOf("-");
        string path = "";
        if (pathIndex != -1)
        {
            path = UserClickModel.mqttRespones.path.Substring(pathIndex + 1).Trim();
        }
        var lastIndex = path.LastIndexOf("\\");
        if (lastIndex != -1)
        {
            path = path.Substring(0, lastIndex);
        }
        var isCopy = false;
        if (!Directory.Exists(programBackupModel.LocalBackupPath))
        {
            Directory.CreateDirectory(programBackupModel.LocalBackupPath);
            isCopy = true;
        }
        else
        {
            var lastDir = FileCommon.GetLastDir(programBackupModel.LocalBackupPath);
            if (string.IsNullOrWhiteSpace(lastDir))
            {
                isCopy = true;
            }
            else
            {
                var oldfileList = new List<FileInfo>(); 
                var newfileList = new List<FileInfo>();
                var suffixs = new List<string> { "*.ap14", "*.ap15", "*.ap16", "*.ap17", "*.ap18", };
                foreach (var item in suffixs)
                {
                    oldfileList.AddRange(FileCommon.PathConvertFile(Directory.GetFiles(lastDir, item, SearchOption.AllDirectories).ToList()));
                    newfileList.AddRange(FileCommon.PathConvertFile(Directory.GetFiles(path, item, SearchOption.AllDirectories).ToList()));
                }
                if (oldfileList.Count == 0 || newfileList.Count == 0)
                {
                    isCopy = true;
                }
                else
                {
                    foreach (var item in oldfileList)
                    {
                        var file1 = newfileList.Where(x => x.Extension == item.Extension).First();
                        if (file1.Length != item.Length || file1.LastWriteTime != item.LastWriteTime)
                        {
                            isCopy = true;
                            break;
                        }
                    }
                }
            }
        }
        string filePath = "";
        ProgramBackupBll backupBll = new ProgramBackupBll();
        if (isCopy)
        {
            var s = new DirectoryInfo(path);
            filePath = backupBll.Copy(s, programBackupModel.LocalBackupPath, UserClickModel.ResId, "PLC", UserClickModel.ProgramName, date);
            backupBll.DeleteDirectory(programBackupModel.LocalBackupPath);
        }
        else
        {
            sysLogBll.InsertLog($"simens not backup,GUID:{UserClickModel.Id}", SysLogType.Info);
        }
        backupBll.AddLog(programBackupModel, db, filePath, UserClickModel, date);
    }
    catch (Exception ex)
    {
        sysLogBll.InsertLog($"GUID:{UserClickModel.Id},error:" + ex.Message);
    }
}
替代备份方案

针对TIA Portal旧版本的文件独占问题,可以尝试以下几种方法:

1. 利用TIA Portal开放API实现备份

西门子提供了TIA Portal的.NET API(Siemens.Engineering命名空间),可以直接调用官方接口导出项目备份,完全避开文件系统层面的锁问题,兼容所有支持API的TIA版本。

关键代码示例:

using Siemens.Engineering;
using Siemens.Engineering.HW;
using Siemens.Engineering.SW;

public void BackupViaTiaApi(string projectPath, string backupPath)
{
    using (var tiaPortal = new TiaPortal())
    {
        var project = tiaPortal.Projects.Open(projectPath);
        // 导出项目为归档文件(支持带依赖项导出)
        project.Export(backupPath, ExportOptions.WithDependencies);
        project.Close();
    }
}

注意:需要引用对应TIA版本的API程序集,且工具运行时TIA Portal需处于已打开目标项目的状态。

2. 延迟备份策略

如果无法使用API,可在用户点击“确认”后延迟一段时间再执行复制操作——TIA Portal完成下载后会逐步释放文件锁,设置10-30秒的延迟(可根据项目大小调整),再尝试复制文件夹。

实现方式(异步延迟避免阻塞主线程):

if (isCopy)
{
    await Task.Delay(TimeSpan.FromSeconds(15)); // 延迟15秒执行复制
    var s = new DirectoryInfo(path);
    filePath = backupBll.Copy(s, programBackupModel.LocalBackupPath, UserClickModel.ResId, "PLC", UserClickModel.ProgramName, date);
    backupBll.DeleteDirectory(programBackupModel.LocalBackupPath);
}

缺点:可靠性依赖延迟时间设置,可能因系统性能、项目大小出现偏差。

3. 自定义文件复制方法绕过独占锁

使用Windows API的CreateFile函数,指定全共享权限打开文件,再读取内容完成复制,绕过默认的文件复制锁限制。

封装的自定义复制方法示例:

using System.ComponentModel;
using System.Runtime.InteropServices;
using System.IO;

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

public void CopyFileWithShare(string source, string destination)
{
    const uint GENERIC_READ = 0x80000000;
    const uint FILE_SHARE_ALL = 0x00000007;
    const uint OPEN_EXISTING = 3;

    var sourceHandle = CreateFile(source, GENERIC_READ, FILE_SHARE_ALL, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
    if (sourceHandle == IntPtr.Zero)
        throw new Win32Exception();

    using (var sourceStream = new FileStream(sourceHandle, FileAccess.Read))
    using (var destStream = new FileStream(destination, FileMode.Create, FileAccess.Write))
    {
        sourceStream.CopyTo(destStream);
    }
}

优势:直接操作文件句柄,绕过部分独占锁;缺点:需要处理复杂的权限和异常情况,无法绕过所有类型的文件锁。

内容的提问来源于stack exchange,提问作者jindeus ye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 11:45:17