现象:

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

异常信息:

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

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

堆栈信息:

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

原因:

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

解决方案:

  重新处理注册表。

代码:

    public class FontsClearup
{
/// <summary>
/// 获取系统文件位置
/// </summary>
[MethodImpl(MethodImplOptions.ForwardRef), SecurityCritical, SuppressUnmanagedCodeSecurity, DllImport("shell32.dll", CharSet = CharSet.Unicode)]
internal static extern int SHGetSpecialFolderPathW(IntPtr hwndOwner, StringBuilder lpszPath, int nFolder, int fCreate); /// <summary>
/// 获取字体文件夹
/// </summary>
/// <returns></returns>
private static string GetFontDir()
{
var lpszPath = new StringBuilder();
return SHGetSpecialFolderPathW(IntPtr.Zero, lpszPath, , ) != ? lpszPath.ToString().ToUpperInvariant() : null;
} public const string FontsRegistryPath =
@"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts";
public const string FontsLocalMachineRegistryPath =
@"Software\Microsoft\Windows NT\CurrentVersion\Fonts"; /// <summary>
/// 获取所有字体信息
/// </summary>
/// <returns></returns>
public static IEnumerable<FontInfo> ScanAllRegistryFonts()
{
var fontNames = new List<FontInfo>();
new RegistryPermission(RegistryPermissionAccess.Read, FontsRegistryPath).Assert();
try
{
var fontDirPath = GetFontDir();
using (var key = Registry.LocalMachine.OpenSubKey(FontsLocalMachineRegistryPath))
{
if (key == null)
{
return Enumerable.Empty<FontInfo>();
}
var valueNames = key.GetValueNames();
foreach (var valueName in valueNames)
{
var fontName = key.GetValue(valueName).ToString();
var fontInfo = new FontInfo
{
Name = valueName,
RegistryKeyPath = key.ToString(),
Value = fontName
};
try
{
var systemFontUri = new Uri(fontName, UriKind.RelativeOrAbsolute);
if (!systemFontUri.IsAbsoluteUri)
{
new Uri(Path.Combine(fontDirPath, fontName));
}
}
catch
{
fontInfo.IsCorrupt = true;
}
fontNames.Add(fontInfo);
}
key.Close();
key.Flush();
}
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
finally
{
CodeAccessPermission.RevertAssert();
}
return fontNames;
} /// <summary>
/// 获取所有异常字体信息
/// </summary>
/// <returns></returns>
public static IEnumerable<FontInfo> GetAllCorruptFonts()
{
var fonts = ScanAllRegistryFonts();
return fonts.Where(f => f.IsCorrupt);
} /// <summary>
/// 整理字体信息
/// </summary>
/// <param name="p_corruptFonts"></param>
public static void FixRegistryFonts(IEnumerable<FontInfo> p_corruptFonts = null)
{
IEnumerable<FontInfo> corruptFonts = p_corruptFonts;
if (corruptFonts == null)
{
corruptFonts = GetAllCorruptFonts();
} new RegistryPermission(RegistryPermissionAccess.Write, FontsRegistryPath).Assert();
try
{
using (var key = Registry.LocalMachine.OpenSubKey(FontsLocalMachineRegistryPath, true))
{
if (key == null) return;
foreach (var corruptFont in corruptFonts)
{
if (!corruptFont.IsCorrupt) continue;
var fixedFontName = RemoveInvalidCharsFormFontName(corruptFont.Value);
key.SetValue(corruptFont.Name, fixedFontName, RegistryValueKind.String);
}
key.Close();
key.Flush();
}
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
finally
{
CodeAccessPermission.RevertAssert();
ScanAllRegistryFonts();
}
} private static string RemoveInvalidCharsFormFontName(string fontName)
{
var invalidChars = Path.GetInvalidPathChars();
var fontCharList = fontName.ToCharArray().ToList();
fontCharList.RemoveAll(c => invalidChars.Contains(c));
return new string(fontCharList.ToArray());
}
} public class FontInfo
{
public string RegistryKeyPath { get; set; }
public bool IsCorrupt { get; set; }
public string Name { get; set; }
public string Value { get; set; } }

执行:FontsClearup.FixRegistryFonts();

其实方法的用法见注释。

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

最新文章

  1. webpack+react配置
  2. 【CC评网】2013.第39周 漂亮的作息表
  3. return、 return false的用法
  4. Android Studio开发环境变量配置
  5. 多线程——GCD
  6. HDU 3998 Sequence (最长上升子序列+最大流)
  7. js模板引擎实现原理
  8. 深入理解GCD ( 二 )
  9. jQuery $.ajaxSend()
  10. HTML5&amp;CSS3读书笔记
  11. typecho for SAE
  12. 【English】十三、英语中的连词有哪些,都有什么作用
  13. 回顾servlet生命周期(代码测试),读取初始化参数
  14. mysql 开发进阶篇系列 52 权限与安全(系统四个权限表的粒度控制关系)
  15. SQL查询数据并插入新表
  16. spring mvc读取properties资源文件夹中文乱码问题
  17. jsp一些使用技巧
  18. servlet及jsp之间的请求转发
  19. CentOS7安装RabbitMQ
  20. Idea的Maven项目引入模块

热门文章

  1. Cause: org.xml.sax.SAXParseException; lineNumber: 45; columnNumber: 62; 元素内容必须由格式正确的字符数据或标记组成。
  2. hibernate经常报的几个不起眼的错误, 都是因为不细心或者手滑了输入有误造成了
  3. SQL dialect is not configured
  4. eclipse搭建struts2环境及所遇到的问题
  5. 一些unity问题的收集
  6. [leetcode]392. Is Subsequence 验证子序列
  7. 20-java 对象链表空没空呢
  8. golang实现任务分发处理
  9. Linux ld命令
  10. dbus通信与接口介绍