信创系统问题解决笔记

本文记述解决信创系统显示问题过程经历,描述遇到的各种问题以及解决方法。

问题描述

测试反馈,在信创系统上,部分界面字体显示异常,表现为内容越界、文字区域显示为小空格,如下图所示:

image.png

初步分析是字体原因,具体情况需要更进一步分析。

问题复现

测试团队的信创测试环境有UOSKylin两个系统,为了不干扰测试团队的测试,选择在本地虚拟机上搭建相同信创环境。

  1. 安装信创系统
    安装UOS系统很顺利,安装Kylin遇到问题。载入镜像之后,虚拟机一直停留在光标闪烁界面,无法进入后续安装流程。经过查阅资料,猜测可能是Vmware版本太低,本地Vmware是版本是12.0.2,准备升级虚拟机

  2. 安装新版虚拟机之前,需要删除旧版本。通过控制版本删除旧版本失败,提示需要什么msi才能卸载,原始安装包早就删掉,无法通过控制面板删除,无奈之下,只好手动删除Vmware安装目录加清理注册表。

  3. 因为本机是Win7,支持Win7Vmware最高版本是 VMware-workstation-full-15.5.6-16341506.exe,于是哼哧哼哧去下载,在安装过程中,提示需要 tools-linux.msi 文件,这就很奇怪,在网上找了半天,下载了多个版本的vmware-tools在里面都没找到 tools-linux.msi ,为什么安装时还要依赖其他文件呢?又在网上搜索解决方案,最后通过下载Windows官方卸载工具 MicrosoftProgram_Install_and_Uninstall.meta,把涉及到Vmware的组件都卸载,然后清理注册表,重启电脑后再次安装新版Vmware,终于安装成功,Kylin系统也顺利安装。

  4. 启动程序。因为信创环境是基于Linux开发的,exe格式的不能直接运行。系统自带的wine是64位,它无法启动32位程序。要么编译64位程序,要么运行32位的wine。

    • 尝试编译64位程序。发现相关依赖的组件不支持64位编译,放弃
    • 尝试运行32位wine。在网上搜索一圈,编译32位的wine,安装流程来走,遇到各种各样的问题,最终放弃。
  5. 回想起测试人员是运行原生包来测试,而我这边是通过wine启动运行,这两者是不是存在区别呢?通过测试对比发现,果然存在区别,同样的操作,在原生包启动和通过wine启动,表现不一样。

    • 转换思路,要么将开发环境的exe打包成新创环境的格式,要么通过第三方启动器运行。
      方法1: 自己打包。咨询了运维同事,将程序打包成deb需要知道各种依赖的情况,较为复杂,不走这条路
      方法2:通过第三方运行期运行。经过调研得知,在UOS系统中,可通过应用商店下载 wine运行器,运行界面如下图:

    image.png

    Kylin系统上,可通过 CrossOver(功能和wine类似)运行,运行界面如下图:

    image.png

    万事俱备,只欠东风。

预备知识

  1. Windows字体基础概念以及绘制方法

  2. GDI+在绘制文字时,遇到不支持的字符会如何处理? GDI+DrawString包含字体回滚机制,当所选字体无法支持显示字符时,会选择其他系统字体来显示,当没有font fallback 发生时,会显示空白方框。

  3. Wine介绍,它将Windows API调用动态翻译成POSIX调用。这是Wine使用手册Wine分为32位和64位,32位只能启动32位程序,64位只能启动64位程序。还有一种支持WoW64机制Wine,运行同时运行32位和64位程序,具体可参考wine实用经验教程

  4. 通过wine运行器启动和 wine ./xxx.exe 启动,两者展示效果不同。通过对比发现是启动Wine的命令行有区别。

    • 显示正常的 WINEPREFIX=~/xx wine xx.exe
    • 显示不正常的 wine xx.exe
      经过搜索和验证,发现是不同容器中的字体不同导致的。
  5. wine命令行启动参数介绍

    • WINEARCH=winxx,指定Windows架构,可设置为Win32或者Win64.
    • WINEPREFIX=路径 指定程序运行容器环境,wine使用虚拟C驱动器,默认路径为 ~/.wine,程序启动后,会在 WINEPREFIX 路径下创建 drive_c/ 等文件夹和文件。要安装一个windows程序,一般在设置好 WINEPREFIXWINARCH 后,再运行程序。
  6. winetricks方便用户配置wine环境,可安装基础DLL、运行库之类的。通过 WINEPREFIX=路径 winecfg 来配置特定路径的容器。一般来说,为每个windows程序建立独立容器,这样各类兼容包、字体和调用的dll都不会相互影响,移植和删除更灵活。

解决尝试

考虑显示异常可能是字体问题后,有如下解决思路。
思路一:当遇到字体不可用时,在本机找另一个可用的字体
思路二:手动安装字体

思路一细化流程:
1. 找出本机当前安装的所有字体
2. 用每种字体都输出相同信息,查看是否显示异常。
3. 找到判断字体显示异常的依据,并将显示正常的字体保存起来。
4. 使用配置字体时,如果发现字体不可用,就从3)种的字体集合中取1个。

结论1:相同内容,会因为输出字体的不同,显示宽度和高度有所区别。
结论2:枚举得到的本机的所有字体,也存在部分字体显示不正常情况
结论3:当所选字体无法显示特定字符时,不同字体表现不一样。有的表现为输出空白小方块,有的显示乱码,还有的中文输出空白小方块,数字正确显示。
结论4:通过对比显示正常和不正常的字体信息,没找到区分字体显示正确与否的依据。最初找到字体的lfCharSet属性,相关定义如下:

image.png

显示正确的值为0,显示错误的值为2。这个区别在Windows系统是可行的,但在信创系统上不行。

尝试通过函数 GetFontLanguageInfo 获得字体信息,用其返回值来区分,测试结果让人失望。

此路不通。

思路二细化流程:
1. 通过wine命令行启动程序,安装字体很麻烦。因此,选择第三方运行器启动。
2. 在本地构建带调试信息的Release版本程序,通过 beyongcompare文件夹同步同步到信创共享目录,因为共享目录读写权限的问题,无法新建文件,需要再从信创共享目录拷贝到信创本地目录,可通过 rsync 或者 beyongcompare文件夹同步实现。
3. 在启动之前,通过第三方运行器安装字体,经过对比验证,发现安装字体的实质就是将下载的字体文件拷贝到到运行容器C盘的Windows\Fonts目录中。

最终,字体显示问题,通过安装缺失字体的方式解决。

小结

此问题花费了将近1个星期,在本地将信创验证环境搭建好,为后续相关问题的解决打下基础,在此小结。

  • 基础环境搭建
    • Win7系统最高可安装 VMware 15.5.6.如果是Win10Win11,可以安装更高版本的 VMware
    • 信创系统安装。安装UOS家庭版,安装Kylin社区版,不要乱升级内核和系统,够用就行。
  • 调试环境搭建
    • 待调试程序构建为Release版本,增加调试信息
    • 安装samba服务,以便从window访问到信创共享目录
    • 使用BeyondCompare的文件夹同步功能或者 rsync的增量拷贝功能同步程序
    • UOS系统使用wine启动器Kylin系统使用CrossOver,不建议从源码编译32位的wine,太繁琐且很难成功。
    • 字体问题,从第三方启动器下载字体,或者从本地Windows系统的 Windows/Fonts 目录中拷贝所有字体
  • 调试手段
    • 打印日志。在网络共享路径,会因权限问题打印失败,因此需要同步到信创本地再打印。为提高效率,可屏蔽不相关日志输出,给日志增加关键字,便于后续定位分析。
    • 弹框提示。在关键路径上,可用弹框提示的方式来指示程序运行路径和状态信息。
    • 系统配置文件要调整为对应环境的配置,不能用windows的环境配置跑在信创环境上。这一点坑了笔者很多时间。介绍下是如何区分不同系统的,方法很简单,在本地增加OSVersion配置项,发布打包时,Windows系统中填 Windows,UOS系
posted @ 2024-08-07 15:47  浩天之家  阅读(159)  评论(0编辑  收藏  举报