DEBUG.WIKI
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →
搬瓦工;先看线路,再选 VPS;CN2 GIA · 对应线路套餐;查看线路 →
阿里云;从建站到云上业务;云服务器 · 数据库 · 对象存储;查看产品 →

WPF 打印生成零字节 PDF,检查弧线角度的小数逗号

文化使用小数逗号时,WPF 的 ArcSegment 旋转角可能被写成非法 XPS 路径。限定同步序列化或打印调用的 CurrentCulture,结束后恢复,并验收生成文件和页面内容。

WPF 打印到 Microsoft Print to PDF,任务没有明显抛错,输出文件却是零字节;诊断里出现 XPS_E_INVALID_MARKUP 或 0x8052000C。如果页面包含带小数旋转角的弧线,并且线程文化是 de-DE、pl-PL 等小数逗号文化,先检查生成的 XPS 路径。

例如弧线角度本应是 -168.65,序列化后却写成 -168,65。路径语法中的逗号又承担分隔作用,参数数量因此错乱。问题不一定出在 PDF 驱动,也不能仅凭输出文件为空就认定源文档没有内容。

对照同一条弧线的序列化文本

已确认的环境包括 .NET 10.0.12;10.0.13 的正式 VisualSerializer 对应路径分支仍直接追加 RotationAngle,未显式指定不变文化。周围的点和半径已采用不变文化,所以可能只有这个角度出问题。

保留原文档、线程文化和错误信息,在受控副本中比较小数逗号文化与 InvariantCulture 的 XPS 输出。确认改变的是同一个 ArcSegment 的小数分隔,而不是两次生成了不同页面。没有弧线或没有小数角度时,不要强套这条原因。

将文化调整限定到同步调用

对于已经确认的同步 XpsDocumentWriter.Write 路径,可以在调用期间临时使用 InvariantCulture,结束后在 finally 中恢复。下面假定 writer、document 已按原流程创建,并在合适的 WPF 线程上使用:

using System.Globalization;

var previousCulture = CultureInfo.CurrentCulture;
try
{
    CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
    writer.Write(document);
}
finally
{
    CultureInfo.CurrentCulture = previousCulture;
}

只改变 CurrentCulture,不需要把整个应用的 CurrentUICulture 或全局默认文化一起改掉。页面中需要本地化的业务文字,应按原流程完成格式化,避免这个局部范围意外改变尚在生成的用户可见内容。

此片段只适用于相关工作确实在同步调用中完成的路径。异步写入或把打印工作转移到其他线程时,必须单独核对文化的传播和恢复时机;不能在启动任务后立即恢复,再认为后台序列化也处于同一范围。

检查文件能读、页面也正确

在临时输出位置重新生成,不覆盖唯一的原始结果。先核对 XPS 中弧线角度使用句点,再用实际消费入口打开文档,检查页数、弧线形状和文字。打印到 PDF 时,还要确认作业完成、文件大小有效且可正常打开,不能只看 Write 返回而没有抛异常。

同时验证调用后的线程文化已恢复,其他区域设置和后续界面行为保持预期。若仍然是零字节文件,继续检查其他 XPS 标记、打印队列和驱动错误,不反复更换小数格式来掩盖新的故障。

升级后保留原来的文化与文档对照用例,重新检查弧线序列化和实际输出,再决定是否移除局部兼容代码。