现象:

  打印时候程序直接崩溃。调试时出现下列异常。

异常信息:

  中文:System.ArgumentException : 路径中有非法字符。

  英文: System.ArgumentException' occurred in mscorlib.dll  Additional information: Illegal characters in path

堆栈信息:

  1. Stack Trace:=
  2.    at System.IO.Path.CheckInvalidPathChars(String path)
  3.    at System.IO.Path.Combine(String path1, String path2)
  4.    at Microsoft.Internal.GDIExporter.BuildFontList(String fontdir)
  5.    at Microsoft.Internal.GDIExporter.CGDIDevice.CheckFont(GlyphTypeface typeface, String name)
  6.    at Microsoft.Internal.GDIExporter.CGDIRenderTarget.CreateFontW(GlyphRun pGlyphRun, Double fontSize, Double scaleY)
  7.    at Microsoft.Internal.GDIExporter.CGDIRenderTarget.RenderTextThroughGDI(GlyphRun pGlyphRun, Brush pBrush)
  8.    at Microsoft.Internal.GDIExporter.CGDIRenderTarget.DrawGlyphRun(Brush pBrush, GlyphRun glyphRun)
  9.    at Microsoft.Internal.AlphaFlattener.BrushProxyDecomposer.Microsoft.Internal..AlphaFlattener.IProxyDrawingContext.DrawGlyphs(GlyphRun glyphrun, Geometry clip, Matrix trans, BrushProxy foreground)
  10.    at Microsoft.Internal.AlphaFlattener.PrimitiveRenderer.DrawGlyphs(GlyphRun glyphrun, Rect bounds, Matrix trans, String desp)
  11.    at Microsoft.Internal.AlphaFlattener.Flattener.AlphaRender(Primitive primitive, List` overlapping, Int32 overlapHasTransparency, Boolean disjoint, String desp)
  12.    at Microsoft.Internal.AlphaFlattener.Flattener.AlphaFlatten(IProxyDrawingContext dc, Boolean disjoint)
  13.    at Microsoft.Internal.AlphaFlattener.Flattener.Convert(Primitive tree, ILegacyDevice dc, Double width, Double height, Double dpix, Double dpiy, Nullable` quality)
  14.    at Microsoft.Internal.AlphaFlattener.MetroDevice0.FlushPage(ILegacyDevice sink, Double width, Double height, Nullable` outputQuality)
  15.    at Microsoft.Internal.AlphaFlattener.MetroToGdiConverter.FlushPage()
  16.    at System.Windows.Xps.Serialization.NgcSerializationManager.EndPage()
  17.    at System.Windows.Xps.Serialization.NgcFixedPageSerializer.SerializeObject(Object serializedObject)
  18.    at System.Windows.Xps.Serialization.NgcDocumentPageSerializer.SerializeObject(Object serializedObject)
  19.    at System.Windows.Xps.Serialization.NgcDocumentPaginatorSerializer.SerializeObject(Object serializedObject)
  20.    at System.Windows.Xps.Serialization.NgcSerializationManager.SaveAsXaml(Object serializedObject)
  21.    at System.Windows.Xps.XpsDocumentWriter.SaveAsXaml(Object serializedObject, Boolean isSync)
  22.    at System.Windows.Xps.XpsDocumentWriter.Write(DocumentPaginator documentPaginator)
  23.    at System.Windows.Controls.PrintDialog.PrintDocument(DocumentPaginator documentPaginator, String description)

原因:

  在注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts 中存的是字体名称及其文件位置的列表。但这些文件位置中有非法字符中有非法字符。在执行Path.Combine方法时,出现异常。

解决方案:

  重新处理注册表。

代码:

  1. public class FontsClearup
  2. {
  3. /// <summary>
  4. /// 获取系统文件位置
  5. /// </summary>
  6. [MethodImpl(MethodImplOptions.ForwardRef), SecurityCritical, SuppressUnmanagedCodeSecurity, DllImport("shell32.dll", CharSet = CharSet.Unicode)]
  7. internal static extern int SHGetSpecialFolderPathW(IntPtr hwndOwner, StringBuilder lpszPath, int nFolder, int fCreate);
  8.  
  9. /// <summary>
  10. /// 获取字体文件夹
  11. /// </summary>
  12. /// <returns></returns>
  13. private static string GetFontDir()
  14. {
  15. var lpszPath = new StringBuilder();
  16. return SHGetSpecialFolderPathW(IntPtr.Zero, lpszPath, , ) != ? lpszPath.ToString().ToUpperInvariant() : null;
  17. }
  18.  
  19. public const string FontsRegistryPath =
  20. @"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts";
  21. public const string FontsLocalMachineRegistryPath =
  22. @"Software\Microsoft\Windows NT\CurrentVersion\Fonts";
  23.  
  24. /// <summary>
  25. /// 获取所有字体信息
  26. /// </summary>
  27. /// <returns></returns>
  28. public static IEnumerable<FontInfo> ScanAllRegistryFonts()
  29. {
  30. var fontNames = new List<FontInfo>();
  31. new RegistryPermission(RegistryPermissionAccess.Read, FontsRegistryPath).Assert();
  32. try
  33. {
  34. var fontDirPath = GetFontDir();
  35. using (var key = Registry.LocalMachine.OpenSubKey(FontsLocalMachineRegistryPath))
  36. {
  37. if (key == null)
  38. {
  39. return Enumerable.Empty<FontInfo>();
  40. }
  41. var valueNames = key.GetValueNames();
  42. foreach (var valueName in valueNames)
  43. {
  44. var fontName = key.GetValue(valueName).ToString();
  45. var fontInfo = new FontInfo
  46. {
  47. Name = valueName,
  48. RegistryKeyPath = key.ToString(),
  49. Value = fontName
  50. };
  51. try
  52. {
  53. var systemFontUri = new Uri(fontName, UriKind.RelativeOrAbsolute);
  54. if (!systemFontUri.IsAbsoluteUri)
  55. {
  56. new Uri(Path.Combine(fontDirPath, fontName));
  57. }
  58. }
  59. catch
  60. {
  61. fontInfo.IsCorrupt = true;
  62. }
  63. fontNames.Add(fontInfo);
  64. }
  65. key.Close();
  66. key.Flush();
  67. }
  68. }
  69. catch (Exception exception)
  70. {
  71. Console.WriteLine(exception);
  72. }
  73. finally
  74. {
  75. CodeAccessPermission.RevertAssert();
  76. }
  77. return fontNames;
  78. }
  79.  
  80. /// <summary>
  81. /// 获取所有异常字体信息
  82. /// </summary>
  83. /// <returns></returns>
  84. public static IEnumerable<FontInfo> GetAllCorruptFonts()
  85. {
  86. var fonts = ScanAllRegistryFonts();
  87. return fonts.Where(f => f.IsCorrupt);
  88. }
  89.  
  90. /// <summary>
  91. /// 整理字体信息
  92. /// </summary>
  93. /// <param name="p_corruptFonts"></param>
  94. public static void FixRegistryFonts(IEnumerable<FontInfo> p_corruptFonts = null)
  95. {
  96. IEnumerable<FontInfo> corruptFonts = p_corruptFonts;
  97. if (corruptFonts == null)
  98. {
  99. corruptFonts = GetAllCorruptFonts();
  100. }
  101.  
  102. new RegistryPermission(RegistryPermissionAccess.Write, FontsRegistryPath).Assert();
  103. try
  104. {
  105. using (var key = Registry.LocalMachine.OpenSubKey(FontsLocalMachineRegistryPath, true))
  106. {
  107. if (key == null) return;
  108. foreach (var corruptFont in corruptFonts)
  109. {
  110. if (!corruptFont.IsCorrupt) continue;
  111. var fixedFontName = RemoveInvalidCharsFormFontName(corruptFont.Value);
  112. key.SetValue(corruptFont.Name, fixedFontName, RegistryValueKind.String);
  113. }
  114. key.Close();
  115. key.Flush();
  116. }
  117. }
  118. catch (Exception exception)
  119. {
  120. Console.WriteLine(exception.Message);
  121. }
  122. finally
  123. {
  124. CodeAccessPermission.RevertAssert();
  125. ScanAllRegistryFonts();
  126. }
  127. }
  128.  
  129. private static string RemoveInvalidCharsFormFontName(string fontName)
  130. {
  131. var invalidChars = Path.GetInvalidPathChars();
  132. var fontCharList = fontName.ToCharArray().ToList();
  133. fontCharList.RemoveAll(c => invalidChars.Contains(c));
  134. return new string(fontCharList.ToArray());
  135. }
  136. }
  137.  
  138. public class FontInfo
  139. {
  140. public string RegistryKeyPath { get; set; }
  141. public bool IsCorrupt { get; set; }
  142. public string Name { get; set; }
  143. public string Value { get; set; }
  144.  
  145. }

执行:FontsClearup.FixRegistryFonts();

其实方法的用法见注释。

参考:http://www.dnsingh.com/MyBlog/?tag=/GDIExporter.BuildFontList

WPF 打印崩溃问题( 异常:Illegal characters in path/路径中有非法字符)的更多相关文章

  1. 【已解决】unity4.2.0f4 导出Android工程报错:Error building Player: ArgumentException: Illegal characters in path. [unity导出android工程 报错,路径含有非法字符]

    使用unity3D开发的一个客户端,需要导出为Android工程,然后接入一些第三方android SDK. unity版本 操作系统为: OS 名称: Microsoft Windows 7 旗舰版 ...

  2. VS2017 v15.8.0 Task ExpandPriContent failed. Illegal characters in path

    昨天更新了VS到最新版本v15.8.0,但是编译UWP出现了操蛋的bug. 谷歌一下,vs社区已经有答案了. 打开.csproj文件,在节点 <PropertyGroup> 里面,加上一行 ...

  3. URLDecoder异常Illegal hex characters in escape (%)

    URLDecoder对参数进行解码时候,代码如: URLDecoder.decode(param,"utf-8"); 有时候会出现类似如下的错误: URLDecoder异常Ille ...

  4. 引擎崩溃、异常、警告、BUG与提示总结及解决方法

    http://www.58player.com/blog-635-128.html [Unity3D]引擎崩溃.异常.警告.BUG与提示总结及解决方法   此贴会持续更新,都是项目中常会遇到的问题,总 ...

  5. WPF打印票据

    最近工作的内容是有关于WPF的,整体开发没有什么难度,主要是在打印上因为没有任何经验,犯了一些难,不过还好,解决起来也不是很费劲. WPF打印票据或者是打印普通纸张区别不大,只是说打印票据要把需要打的 ...

  6. WPF 打印实例

    原文:WPF 打印实例      在WPF 中可以通过PrintDialog 类方便的实现应用程序打印功能,本文将使用一个简单实例进行演示.首先在VS中编辑一个图形(如下图所示).      将需要打 ...

  7. 【Bug】解决 SpringBoot Artifact contains illegal characters 错误

    解决 SpringBoot  Artifact contains illegal characters错误 错误原因:Artifact包含非法字符(大写字母) 解决方法:将Artifact名称改成小写 ...

  8. IDEA中新建SpringBoot项目时提示:Artifact contains illegal characters

    场景 一步一步教你在IEDA中快速搭建SpringBoot项目: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/87688277 ...

  9. Linux curl遇到错误curl: (3) Illegal characters found in URL

    服务器上执行一个脚本,在linux新建的sh,把本地编辑器的内容粘贴到文件里. 结果执行的时候报错了. 问题就是 curl:(3)Illegal characters found in URL 看着一 ...

随机推荐

  1. 我在JS上解惑之路1

    1.为什么既然存在等号(==)非等号  (!=),又会有全等号(===)非全等号(!==)? *唯一的不同是后者判断时不进行类型转换. 例:var sNum = "66"; var ...

  2. Java GC的原理

    Java GC(garbage collec,垃圾收集,回收) GC是对JVM中的内存进行标记和回收,Sun公司的JDK用的虚拟机都是HotSpot 对象化的实例是放在heap堆内存中的,这里讲的分代 ...

  3. oracle中的分支与循环语句

    分支语句 if的三种写法一, if 2 < 1 then dbms_output.put_line('条件成立'); end if; 二, if 2 < 1 then dbms_outpu ...

  4. poj3186(区间DP)

    题目链接:http://poj.org/problem?id=3186 思路: 区间DP,给treat编号为1..n,状态很明显是上界i和下界j,dp[i][j]表示从下标i到下标j之间数据的最大价值 ...

  5. 64位tomcat不能配32位的JDK使用

    警告: The APR based Apache Tomcat Native library failed to load. The error reported was [D:\apache-tom ...

  6. SSH框架整合的其它方式

    --------------------siwuxie095 SSH 框架整合的其它方式 1.主要是整合 Spring 框架和 Hibernate 框架时,可以不写 Hibernate 核心配置文件: ...

  7. 无法打开登录所请求的数据库 "****"。登录失败

    错误:无法打开登录所请求的数据库 "****".登录失败.用户 '****' 登录失败. sql2005连接时出现的错误 解决方法:权限不够,给登录名授权,赋予管理员角色,在登录名 ...

  8. Ubuntu-18.04Python2与Python3自由切换

    一.配置ssh链接 安装openssh-server devops@devops-virtual-machine:~$ sudo apt-get install openssh-server 二.安装 ...

  9. git pull和git fetch命令

    git pull和git fetch命令 git pull git pull命令的作用是取回远程主机某个分支的更新,在与本地指定分支合并,格式如下: $ git pull <远程主机名>& ...

  10. Easyui form 处理 Laravel 返回的 Json 数据

    默认地,Easyui Form 请求的格式是 Html/Text,如果服务端 Laravel 返回的数据是 Json 格式,则应当在客户端进行解析.以下是 Easyui 官方文档的说明: Handle ...