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

C#调用ExifTool读取XML元数据遇未闭合错误,求替代方案

解决ExifTool XML输出不完整问题的替代方案

你的代码在异步读取输出时,可能因OutputDataReceived回调的行读取特性(丢失无换行的末尾数据)、或部分文件元数据异常导致ExifTool生成不规范XML,引发标签未闭合错误。以下是几种可靠的替代方案:

方案1:修复原代码的同步读取方式

异步读取容易丢失部分输出内容,改用同步读取所有输出可避免这个问题:

try
{
    string args = $"-X \"{file}\"";
    ProcessStartInfo pi = new ProcessStartInfo("exiftool.exe", args)
    {
        StandardOutputEncoding = Encoding.UTF8,
        StandardErrorEncoding = Encoding.UTF8,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        UseShellExecute = false,
        CreateNoWindow = true
    };
    using (Process proc = new Process())
    {
        proc.StartInfo = pi;
        proc.Start();
        // 一次性读取全部输出,避免分段丢失
        string stdout = proc.StandardOutput.ReadToEnd();
        string stderr = proc.StandardError.ReadToEnd();
        proc.WaitForExit(10000);
        
        if (proc.ExitCode == 0)
        {
            xml.LoadXml(stdout);
        }
        else
        {
            throw new Exception(stderr);
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

方案2:转用JSON输出再转换为XML

ExifTool的JSON输出稳定性远高于XML,不会出现标签未闭合问题,可先获取JSON再转成XML结构:

using System.Xml;
using Newtonsoft.Json;

try
{
    string args = $"-j \"{file}\""; // 用-j参数输出JSON格式
    ProcessStartInfo pi = new ProcessStartInfo("exiftool.exe", args)
    {
        StandardOutputEncoding = Encoding.UTF8,
        StandardErrorEncoding = Encoding.UTF8,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        UseShellExecute = false,
        CreateNoWindow = true
    };
    using (Process proc = new Process())
    {
        proc.StartInfo = pi;
        proc.Start();
        string jsonOutput = proc.StandardOutput.ReadToEnd();
        string stderr = proc.StandardError.ReadToEnd();
        proc.WaitForExit(10000);
        
        if (proc.ExitCode == 0)
        {
            // 将JSON序列化为XML
            var jsonObj = JsonConvert.DeserializeObject(jsonOutput);
            XmlDocument xmlDoc = new XmlDocument();
            using (var stringWriter = new StringWriter())
            {
                JsonConvert.SerializeXmlNode(jsonObj, stringWriter, Newtonsoft.Json.Formatting.Indented);
                xmlDoc.LoadXml(stringWriter.ToString());
            }
            // xmlDoc即为目标XML元数据
        }
        else
        {
            throw new Exception(stderr);
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

方案3:使用原生/第三方.NET库替代ExifTool

如果不想依赖外部工具,可选择以下库:

MetadataExtractor(轻量开源,NuGet可安装)

using MetadataExtractor;
using System.Xml.Linq;

try
{
    var directories = ImageMetadataReader.ReadMetadata(file);
    // 构建符合需求的XML结构
    XNamespace rdfNs = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
    XElement root = new XElement(rdfNs + "RDF");
    XElement description = new XElement(rdfNs + "Description");
    
    foreach (var directory in directories)
    {
        foreach (var tag in directory.Tags)
        {
            description.Add(new XElement(tag.Name, tag.Description));
        }
    }
    
    root.Add(description);
    // root就是生成的XML元数据
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

.NET原生API(适用于图片/文档)

对于图片文件,可使用System.Drawing.Imaging读取元数据;对于Office文档,可使用DocumentFormat.OpenXml。这类API无需外部依赖,但支持的文件类型相对有限。

方案4:优化ExifTool参数

给ExifTool添加参数强制输出规范XML:

  • -n:禁用友好格式化,输出原始值,避免特殊字符导致的输出截断
  • -l:使用长标签名,提升XML可读性

修改后的参数:

string args = $"-X -n \"{file}\"";

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:19:52