首页 > 代码库 > Citrix XenApp和XenDesktop 打印系统解析②
Citrix XenApp和XenDesktop 打印系统解析②
三、思杰通用打印解决方案
思杰的通用解决方案推出的时间很久了,在2004年的思杰iForum大会上,Citrix宣布推出通用打印机驱动程序(UPD)并激动的宣布,Citrix已经永久性的解决了打印的问题。但是事实上,激情之后发现其实通用打印机驱动程序也没有彻底的解决打印问题。其实打印问题长久的悬而未决是微软的问题,思杰只是创造了一些工具,从而使得打印更加的轻松。
思杰的通用打印解决方案,采用了Citrix开发的通用驱动程序(UPD)与底层网络基础设施,允许该驱动程序远程操作所有客户端打印机的设置。基于这个UPD基础之上,Citrix开发新的打印组件:Citrix Universal PrintServer(UPS)思杰通用打印服务器、Citrix UniversalPrinter(CUP)思杰通用打印机和Citrix PDFPrinter(CPP)思杰PDF打印机。形成了多元的思杰通用打印解决方案。
3.1、解决方案组件
思杰通用打印解决方案的组件如图所示:
我们首先介绍这几个组件:
3.2、Citrix Universal PrintDriver(UPD)
3.2.1、Citrix UPD的设备无关性
Citrix Universal PrintDriver中文全称是思杰通用打印机驱动程序,简称UPD。UPD是一个与设备无关的打印驱动程序,其被设计为允许在任何打印机上打印。Citrix的目标是通过UPD减少所需的驱动程序的数量从而简化打印机驱动程序的管理。
这里我们引出UPD的一个特性,设备无关性,什么是设备无关性呢?在早期的应用程序开发中针对打印机的使用是需要应用程序的开发者了解硬件的。这成了程序员的负担,同时也使开发好的程序难以移植。要实现设备无关性,我们需要先明白在操作系统中的“设备上下文(DeviceContext)”的概念。设备上下文(DeviceContext)简称DC,DC可以理解为一个物理设备在操作系统中的抽象,比如一台物理打印机,操作系统不能实际的看到这台物理的打印机也不能实际的模到它,但操作系统想使用它。怎么办呢?这就需要另外一个人将这个打印机抽像出来并告诉操作系统。通过什么方法去抽象这台打印机呢?比如我旁边有一个白板,你们看不到它。但是我可以告诉你们,这个白板在我的左边,大小是600mm x 900mm,备有一个板擦和一支黑色的记号笔,这个白板就在你的脑中抽像出来了。当你想使用它的时候,你可以告诉我:拿起黑色的记号笔,从(100mm,200mm)开始划条线到(200mm,300mm)的地方。我照做后,将与你期望的结果一致。这些信息就是白板抽像出来的DC。各种图形设备都可以抽像成一个DC。这个DC可以是一个显示器,可以是一个喷墨打印机,也可以是一个激光打印机。对各种DC的操作大体上并无不同。这就大大方便了开发者,也使应用程序不再局限于设备。应用程序开发者不再需要了解硬件的知识,只要知道如何使用DC就可以在各种不同的设备上实现想要的效果。
因此,我们就可以给设备上下文(DC)一个定义:DC是一种包含有关某个设备(如显示器或打印机)的绘制属性信息的Windows数据结构。所有绘制调用都通过设备上下文对象进行,这些对象封装了用于绘制线条、形状和文本的 Windows API。设备上下文允许在Windows中进行与设备无关的绘制。设备上下文可用于绘制到屏幕、打印机或者图元文件。理解了设备上下文,设备无关性就好理解了。比如用GDI画圆命令在显示器的DC上画了一个圆,同样的处理只需要将DC换成各种厂家的打印机DC,就可以在打印机上打印同样的一个圆。这就是设备无关性。
3.2.2、Citrix UPD的组成
接下来我们看看思杰UPD的组成部分:
服务器组件:在XenApp服务器或基于XenDesktop的虚拟桌面上,思杰通用打印机驱动程序集成在XenApp/ XenDesktop的VDA中,在安装VDA组件的时候自动进行安装。当应用程序的打印作业需要此驱动程序或者说启用通用打印时,此驱动将应用程序的打印数据直接输出,数据不做任何修改,并经由ICA / HDX协议发送到用户的客户端。
客户端组件:思杰UPD的客户端组件也集成在Citrix Receiver里面,在Citrix Receiver安装的时候一并进行附带安装。它获取接受的打印流的XenApp服务器或XenDesktop虚拟桌面的打印数据,并将其转发到本地Windows的打印子系统,然后利用Windows原本的打印机驱动程序进行打印作业。
其打印的基本流程如下图所示:
该Citrix通用打印机驱动程序(UPD)在所有Citrix桌面或应用服务器上会安装它的驱动,同时,在客户端上也运行着该通用打印驱动程序(UPD)。在实际的打印过程中,打印文档需求的一些打印机设置直接从客户端(带智能缓存)检索,比如打印机的属性等信息。
下图表示了使用UPD后,在VDA上远程去操作本地客户端上的打印机的设置。
这些打印机的功能和打印机的服务是由本地客户端的打印机真实的驱动去读取的。通用驱动程序(UPD)不理解也并不需要理解这些打印机的设置或者选项。通用驱动程序(UPD)只是将文档打印设置选项以及需求传递给远程客户端,并由远程客户端去真实的打印机驱动里面进行应答。这个行为在Windows打印中学名叫作:应用程序应答。
因此,使用通用打印驱动程序(UPD),就不需要在XenApp/XenDesktop服务器上安装打印机的驱动,只需要在本地客户端安装打印机的真实的驱动即可,Citrix的通用驱动(UPD)只是一个中介,承载Citrix后端的打印任务并传送到客户端本地,然后交由客户端本地真正的打印机驱动去进行打印。
3.2.3、Citrix UPD截获数据过程
那么UPD的服务器端组件是如何在XenApp服务器或XenDesktop的虚拟桌面获取打印数据的?
我们通过下图来逐步进行讲解:
Windows的打印机制是一个模块化的系统,由打印假脱机 (Print Spooler)和一套打印机驱动组成。其功能可分为五个模块:打印假脱机系统的打印处理器、语言监视器和端口监视器;打印机驱动程序的打印图形DLL和打印接口DLL。如上图。
一个完整的打印流程是这样的:
1、用户通过打印机的属性界面,调用打印接口DLL枚举打印机和设置打印文档的属性;
2、操作系统调用打印机驱动创建设备上下文(DC),应用程序操作设备上下文,调用GDI中函数(基于WPF框架开发的应用程序不用调用GDI,而是直接生成XPS纸张规范格式)发出的打印请求并初始化打印机;
3、打印接口DLL调用GDI函数进行绘图操作,将绘图记录保存在EMF文件中,如果是PCL或者XPS,直接输出为XPS或者PCL文件;
4、重复绘图操作直到绘图完成,并生成一个完整的EMF文件,然后WinSpool.drv打印客户端通过RPC发送到打印假脱机程序(Print Spooler)。
5、打印处理器调用GDI的绘图引擎(GDI Rendering Engine),在打印图形DLL等插件协助下,把EMF文件中的绘图命令逐条解析到Spooler File(Windows下是.SPL和.SHD后缀的文件)中。Spooler File是打印假脱机的缓存文件池。
6、打印机假脱机系统的语言监视器开始工作,根据打印机的打印控制语言,打印假脱机的缓存文件被用来发送Postscript命令或者PCL命令到Postscript打印机或者HP打印机(PCL是HP打印机的控制语言,当然别的很多打印机也支持PCL),Postscript命令或PCL命令能够被打印机理解。
7、打印语言监视器调用打印端口监视器,端口监视器向下调用内核中的总线端口驱动程序并将打印机命令发送给物理打印机。
在这个过程中我们可以看到,我们能够获取数据的地方有三个:
第一个:在驱动生产打印假脱机文件传递给打印假脱机程序之前截获;
第二个:直接将打印假脱机的缓存文件拿出来或者拷贝一份;
第三个:在端口监视器将数据转发给内核中的总线端口驱动的时候进行数据截断;
实际上在Citrix的打印解决方案中,前两个方法都会被使用到。第一个方法是给Citrix Universal PrintDriver(UPD)使用的,第二个方法是给Native Printer Driver(NPD)使用的。第三种方法为什么没用呢?毫无疑问,第三种方法中,直接截获的是打印机的指令,必须是支持这种打印机指令的打印机才能够进行打印作业,这种方法下兼容性对打印机的兼容性最差,需要相对应的打印机型号才行。
如上图,Citrix Universal PrintDriver(UPD)通过在Spoolsv.exe进程的上面使用Citrix API Hook钩子技术,将WinSpool.drv打印客户端传递过来的打印假脱机文件进行截获,并传递给ICA/HDX协议传输到用户客户端。这个API Hook钩子就是UPD Hook。说道这儿我想大家已经明白了大体的流程:
简要说明上图流程:
1、运行在XenApp服务器或XenDesktop虚拟桌面上的应用程序请求打印。
2、应用程序通过调用打印驱动程序以及相关图形API创建或绘制EMF文件(如果是XPS格式的话,就需要通用驱动程序去调用Windows的通用驱动程序,然后进行XPS和EMF的转换操作,这个在之前的文章有所阐述)。
3、EMF文件被发送到操作系统上的打印后台处理程序上。
4、正常情况下打印后台处理程序使用适当的打印机驱动程序来创建用于打印机进行打印的假脱机文件。但是在思杰“通用打印驱动程序。”模式下,此驱动程序根本不会根据EMF文件创建打印假脱机文件,而是通过API Hook拦截发送给Print Spooler的EMF文件。
5、通用打印驱动程序将拦截的EMF文件经由ICA/HDX协议打印通道传递到到Citrix Receiver客户端。
6、Windows 的Citrix Receiver客户端接收EMF文件。并转移到Citrix Receiver客户端的通用打印组件处理。
7、客户端的通用打印驱动程序组件将该文件传递给客户端上的WIndows本地打印假脱机系统处理(Spooler),然后继续Windows的打印处理过程,调用本地的打印驱动程序,开始生成打印假脱机文件。
8、最后,打印假脱机系统将其打印作业发送到适当的打印机。
3.2.4、Citrix UPD的演变
在这个过程中,Citrix UPD模式使用的格式是EMF。实际上在Citrix UPD之前的版本中,默认使用的并不是EMF。
现在我们所使用的Citrix UPD是V3的版本,也就是说这是Citrix UPD的第三个发行版本。其版本演变如下:
UPD V1:这个版本是基于Citrix MetaFrame XPFR1的推出发行的,其发行日期为2004年。其默认使用的格式是PCL4而并不是EMF。这个主要是在当时,Citrix和HP公司签署了一项合作,Citrix公司OEM惠普的PCL4以及相关的打印驱动来开发UPD V1的版本。在当时,PCL最新的版本就是PCL4。
UPD V2:这个版本主要是基于Citrix MetaFrame XPFR3推出的更新,当时包括HP业以推出了最新的PCL 5c的打印机控制语言,同时,在这个版本中,添加了一些颜色打印方案和打印dpi的提升。其默认使用的格式是PCL5c。
UPD V3:直到Citrix推出Presentation Server4.0之后,才推出了UPD V3的版本。这个版本一直沿用至今。在这个版本中,Citrix不在使用PCL作为默认的打印文件格式,而是使用微软的EMF作为默认的打印文件格式。同时,也在该版本中添加了对XPS的支持。
而作为这三个版本的演变,我们通过下图加深理解:
在UPD V1的时候,其截获的数据文件流程图:
如图,在UPD V1版本的时候,其使用PCL4语言,因此其用PCL4语言描述的文件就是PCL4文件。
在UPD V2的时候,其截获的数据文件流程图:
3.2.5、Citrix UPD的打印文件格式以及工作原理
在Citrix UPD V3的版本中,默认使用EMF,但是也支持XPS等格式。
下面罗列了Citrix UPD支持的打印格式:
增强型图元文件格式(EMF)(默认)。 EMF是32位版本的Windows图元文件(WMF)格式。什么是图元文件呢?应用程序经常需要相互交换图形数据,这需要将图形数据存放成文件格式。这种文件格式就是图元文件。例如,用户可能使用CAD复杂的特效来设计线条艺术,用PhotoShop编辑真实图像,用Word做文字处理,当这些应用程序一起工作时,它们需要一种通用的数据供它们读写,并交换图形数据。那么每一个应用程序都会创建这么一个图元文件。
XML纸张规格(XPS)。XPS驱动程序使用XML创建一个独立于平台的“电子纸”,类似Adobe的PDF格式。XPS打印作业倾向于具有更小的体积,但在打印作业开始的时候,需要一直等到打印机收到作业的最后一页才会开始打印,EMF则可以边接收边开始打印。如果应用程序支持Windows演示基础(WPF)格式以及打印机支持XPS格式。那么就这可以直接使用XPS进行打印作业了。如果任何一个不被支持,那么打印作业将被转换为EMF格式。
打印机命令语言(PCL5c和PCL4)。PCL最初是由惠普为喷墨打印机开发的一款打印协议。现在的PCL广泛支持HP LaserJet和多功能外设。最新的是PCL6,但是Citrix UPD并不支持PCL 6。PCL5c和PCL4主要是Citrix UPD V1和V2支持,并在V3中保持向上兼容。
PostScript(PS)。PostScript是一种计算机语言,可以用于打印文字和矢量图形。它一方面是一种具有很强图形功能的通用程序设计语言,另一方面又是一种具有一般程序设计语言特性的页面描述语言。也就是说,PostScript具有通用程序设计语言和页面描述语言的双重特征。PostScript是Adobe公司开发的,属于收费的语言,任何公司和产品要使用PostScript都得向Adobe公司缴纳费用。同时,PostScript语言还属于直接打印假脱机文件,其直接省略了打印假脱机系统的渲染或者解析步骤,直接发送给打印机,由打印机对指令的内容进行渲染和绘制。这种直接打印文件的优势很明显,将渲染工作交给打印机,可以减少系统的负担。这类文件比较少见,目前也就是HP格式的PCL6和Adobe的PostScript是属于这类型的直接打印文件和打印机控制语言。该驱动程序主要在高成本的打印机和多功能外围设备使用。
PCL和PS驱动程序除了在Windows上受支持外,还支持非Windows的客户端,比如Mac、Linux或UNIX客户端。而且也是这样的,在Citrix Receiver的Linux客户端上,由于Linux系统并不支持Windows系统的EMF和XPS,因此也没法使用基于EMF和XPS打印文件格式的驱动程序。注:可以根据Citrix的“通用驱动程序优先”策略改变思杰UPD使用驱动的顺序。
根据被支持的打印文件格式,我们来说明一下Citrix UPD打印机驱动程序的工作原理:
一个应用程序通过调用图形驱动界面(GDI)或者WPF创建一个打印任务。如果是GDI的,不管打印任务的初始输出格式是否为EMF格式,本地打印服务程序的任务生成API都会创建一个缓冲文件。如果是XPS的,直接生成XPS的格式,之后该任务在进入本地Windows的Print Spooler打印子系统时,Citrix API Hook钩子就将其发送过来的的EMF/XPS/PS/PCL4/PCL5c文件拦截,因此本地的Print Spooler不会接收到应用程序发送过来的打印数据。而Citrix的API Hook将数据截取过来之后,Citrix UPD反而将打印文件重新封装,然后经ICA/HDX协议的虚拟打印通道传送给前端的Citrix Receiver。
Citrix Receiver终端将接收到的数据拆装, 然后传入Citrix UPD,Citrix UPD会根据打印的格式做相应的处理:
1、如果格式是EMF时,转发至本地Print Spooler,本地Print Spooler会首先生成Spooler File并存储在缓存中,然后根据语言监视器判断,打印机是否支持EMF格式的打印,如果不支持,EMF打印处理器就会将数据返回给GDI,在打印机图形DLL的帮助下,转换成RAW格式。转换后的数据流能够通过本地打印服务程序在送回打印机(不再重新被缓冲)。
2、如果格式是PCL4或者PCL5c时,如果是Windows的客户端,转发至本地Print Spooler,本地Print Spooler会首先生成Spooler File并存储在缓存中,然后根据语言监视器判断,打印机是否支持PCL4或PCL5c格式的打印,如果不支持,驱动打印处理器就会将数据返回给GDI,在打印机图形DLL的帮助下,转换成RAW格式。如果是Linux的客户端, Linux的CUPS(Common UNIXPrinting System,Linux/Unix平台的首选打印系统)中通过打印机驱动进行渲染,然后判断打印机是否支持PCL4以及PCL5c,如果不支持,则需要CUPS将转化为打印机能够识别的数据,比如PostScript数据。注:Linux系统中最长见的打印格式支持是PCL和PostScript。
3、如果格式是XPS时,转发至本地Print Spooler,本地Print Spooler会首先生成Spooler File并存储在缓存中,然后根据语言监视器判断,打印机是否支持XPS格式的打印,如果不支持,XPS驱动会首先调用XPS转EMF处理器,将XPS文件转换为EMF格式,再去判断EMF是否支持,不被支持时,再由打印处理器将数据返回给GDI,在打印机图形DLL的帮助下,转换成RAW格式。
4、如果格式是PostScript时,如果是Windows的客户端,那么就转发至本地的Print Spooler,本地的Print Spooler直接将PS文件转发至打印机。如果是Linux的系统,Linux的CUPS(Common UNIXPrinting System,Linux/Unix平台的首选打印系统)将打印数据直接输出到打印机。如果打印机不支持PostScript,而是PCL的打印机,,则需在CUPS中通过打印机驱动将PostScript转化为PCL数据。
3.2.6、Citrix UPD的组件
上述以及说明了Citrix UPD的打印前驱动程序锁支持的打印格式,那么Citrix的UPD都开发了那些组件来支持这些打印格式呢?下面我们来看看Citrix UPD的组件。
在Windows XP操作系统的32位或64位版本中,那个时代的Citrix UPD属于V1的版本,因此其开发了如下的组件用于支持上述的打印文件格式:
Citrix UniversalPrinter
Citrix XPS UniversalPrinter
HP Color LaserJet
HP Color LaserJet PS
HP LaserJet Series II
打开Windows XP下的通用打印驱动程序,我们可以看到其上所列的组件:
在Citrix UPD V2版本下,其组件由有所变化:
Citrix UniversalPrinter
Citrix XPS UniversalPrinter
HP Color LaserJet 4500PCL 5
HP Color LaserJet 4500PS
HP LaserJet Series II
如图所示:
在Citrix UPD V3版本的时候,其组件如下:
Citrix UniversalPrinter
Citrix XPS UniversalPrinter
HP Color LaserJet 2800Series PS
如下图所示:
就V3版本的这三个组件来说,其各自支持的打印文件格式有所不同, Citrix Universal Printer是用于支持EMF/PCL4/PCL5c的组件;Citrix XPS UniversalPrinter是用于支持XPS的组件;HP Color LaserJet 2800Series PS用于支持PostScript的组件。
3.2.7、Citrix UPD的优势与不足
Citrix UPD这种方式有诸多优点:
1) 体验好。在大型的安装和部署环境中,可以通过使用Citrix UPD来减少对后端系统的打印机驱动程序的维护量,并且有相同的打印机属性页给到用户,提供一致的用户体验。
2) 打印稳定性更高。XenApp服务器或XenDesktop虚拟桌面与Citrix Receiver终端之间实际传输的是文件, 其稳定性和可靠性比基于网络的USB通信协议的传输方式更高。
当然,UPD 技术也有明显的局限性,:
1)客户端上大量打印机驱动的维护问题;
2)使用Windows终端的操作系统所具有的许可成本.;
3)不支持打印机的高级特性;
4)打印设计问题:比如不检查打印的适当的对齐和格式;
5)在使用特定应用程序的时候与打印机存在兼容性问题等等。
接下来我们来讲解Citrix UPS!欢迎大家指点,共同进步。
本文出自 “我拿流年乱了浮生” 博客,请务必保留此出处http://tasnrh.blog.51cto.com/4141731/1855178
Citrix XenApp和XenDesktop 打印系统解析②