WPF 打印崩溃问题( 异常:Illegal characters in path/路径中有非法字符)
2024-10-19 15:33:25
现象:
打印时候程序直接崩溃。调试时出现下列异常。
异常信息:
中文: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
最新文章
- webpack+react配置
- 【CC评网】2013.第39周 漂亮的作息表
- return、 return false的用法
- Android Studio开发环境变量配置
- 多线程——GCD
- HDU 3998 Sequence (最长上升子序列+最大流)
- js模板引擎实现原理
- 深入理解GCD ( 二 )
- jQuery $.ajaxSend()
- HTML5&;CSS3读书笔记
- typecho for SAE
- 【English】十三、英语中的连词有哪些,都有什么作用
- 回顾servlet生命周期(代码测试),读取初始化参数
- mysql 开发进阶篇系列 52 权限与安全(系统四个权限表的粒度控制关系)
- SQL查询数据并插入新表
- spring mvc读取properties资源文件夹中文乱码问题
- jsp一些使用技巧
- servlet及jsp之间的请求转发
- CentOS7安装RabbitMQ
- Idea的Maven项目引入模块
热门文章
- Cause: org.xml.sax.SAXParseException; lineNumber: 45; columnNumber: 62; 元素内容必须由格式正确的字符数据或标记组成。
- hibernate经常报的几个不起眼的错误, 都是因为不细心或者手滑了输入有误造成了
- SQL dialect is not configured
- eclipse搭建struts2环境及所遇到的问题
- 一些unity问题的收集
- [leetcode]392. Is Subsequence 验证子序列
- 20-java 对象链表空没空呢
- golang实现任务分发处理
- Linux ld命令
- dbus通信与接口介绍