Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 600|回复: 0

WPF 打印崩溃问题( 异常:Illegal characters in path/路径中有非法字符)

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-8-30 11:45:08 | 显示全部楼层 |阅读模式

    现象:

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

    异常信息:

      中文: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`1 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`1 quality)
       at Microsoft.Internal.AlphaFlattener.MetroDevice0.FlushPage(ILegacyDevice sink, Double width, Double height, Nullable`1 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(260);
                return SHGetSpecialFolderPathW(IntPtr.Zero, lpszPath, 20, 0) != 0 ? 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...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-3 12:24 , Processed in 0.106278 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表