房子好很差,對我而言始終都是肉體的棲居。對於靈魂,我歷來不知道該去向何處。程序員
首先附上查找Windows打印相關內容的連接,這個分類下包含了Windows打印的方方面面:數據庫
https://msdn.microsoft.com/en-us/library/windows/hardware/ff551767(v=vs.85).aspx編程
如上圖所示,Windows的打印體系結構是由一個打印機假脫機程序(Spooler)和一系列的打印驅動組成。其中帶方框的部分都是能夠編寫安裝的。其中的打印驅動程序是指微軟的統一驅動,也就是系統默認的驅動,而迷你驅動就是在此基礎上進行個性化定製。windows
迷你驅動包括GPD文件和資源DLL,GPD文件就是一個腳本,定義了「打印機首選項」中將出現那些設置,有哪些選項可選,資源DLL就是一個僅僅包含Resource的DLL,提供給GPD使用其中的資源。服務器
而在打印假脫機中:網絡
打印處理器(也就是打印機驅動程序)負責SPL文件操做 EMF/RAW文件操做等;架構
Render-Plugin則能夠對渲染繪製過程進行特殊的處理;併發
UI-Plugin 就是在「打印機首選項」中定義一些特殊的設置頁面。框架
語言監視器以及端口監視器和網絡打印提供者咱們在打印假脫機中進行介紹。ide
打印假脫機程序在Windows系統中主要表現就是Windows後臺打印程序Print Spooler(Spoolsv.exe)。那麼什麼是打印假脫機程序(Spooler)呢?顧名思義,咱們只須要明白「假脫機」的概念,基本上就明白了什麼是打印假脫機程序(Spooler)。
在幾乎全部的操做系統中,外部設備與系統交互都存在兩種模式:聯機模式和脫機模式。
所謂聯機模式是指系統徹底按照外部設備的執行順序執行設備操做,再者外部設備每每都是搶佔式設備,當一個進程須要使用外部設備時每每要等其它進程使用完畢才能夠進行使用。例如:聯機模式下當進程有輸入/輸出需求時就只能在輸入/輸出設備空閒時才能使用設備,若是當前該設備正在被佔用,則該進程就只能等待調用者調用結束才能獲取設備使用權,因此聯機模式最大的缺點就是進程之間不能"併發"地使用設備。
而脫機模式正好與聯機模式相反,脫機模式中提出一個概念就是緩衝區的概念,例如:在脫機模式下,當進程須要輸出數據到外部設備時,首先將數據輸出到緩衝區內,而後外部設備再從緩衝區獲取須要輸出的數據。這樣作很好遙免了聯機模式下進程間不能併發的問題。可是脫機模式很大的一個弊端也凸顯出來,那就是當有數據輸出到緩衝區內時,設備並非立馬對數據進行輸出處理,而是等待緩衝區滿或者進程須要輸出設備輸出的時候,設備才能啓動並將數據輸出至設備進行處理。這樣作會下降設備處理能力,而且頻繁的啓動設備很容易形成設備損壞。
假脫機系統,顧名思義不是真的脫機,它是假的脫機模式。它的真實含義是在聯機的模式下獲得脫機效果。假脫機的最終目標是沿用聯機和脫機的全部優勢同時避免聯機和脫機的全部缺點。因此打印機是一個相對來講比較特殊的硬件。不但不一樣於顯卡這種機箱內的硬件,也不一樣於鼠標鍵盤等外設。鼠標鍵盤顯示器等都是即時反應的,好比移動一下鼠標操做系統都會當即處理並反應在顯示器上。但打印機不是,打印一個文檔快則幾秒,慢則有數十分鐘。操做系統不可能一直等到打印機處理結束再進行返回。因此,操做系統提供了一個叫Spooler的服務來對各類打印機的任務進行管理。Spooler的服務所提供的這個服務有人也將其稱之爲打印池。無論稱呼如何,其技術在操做系統領域中給它的定義是:Spooling技術是一種在多道程序環境下模擬脫機方式控制I/O設備進行輸入輸出的技術。Spooling技術的最終目的是經過系統軟件的方式把只能讓一個用戶獨佔的設備變成多用戶多進程共享的設備,這種作法不只可實現進程能夠隨時調用設備也能夠提升設備的利用率。由於只有當緩衝區沒有任務的時候設備纔會進入休眠狀態,同時還下降了對設備進行休眠和喚醒的操做頻率,延長了設備壽命。
所以在這裏咱們總結一下打印假脫機程序(Spooler)的做用。
打印假脫機程序由一系列的微軟提供的和可選的渲染組件組成,他們的做用包括:
1、檢測打印任務是在本地打印仍是網絡打印。
2、接受GDI和打印驅動爲特定類型的打印機所提供的數據流。
3、緩衝繪製數據到文件中。
4、從邏輯打印隊列中選出第一個有效的物理打印機。
5、將緩衝的數據流(如EMF)轉換成能被打印機硬件所識別的格式(如PCL)。
6、發送打印數據流到打印機硬件中。
7、爲假脫機組件和打印機的相關信息維護一個基於註冊表的數據庫,這個數據庫的咱們在後面會講到。
說道打印假脫機(Spooler)的架構,咱們就不得不提一下Windows的通用圖形接口,不然無法繼續介紹打印假脫機(Spooler)的架構。
對於如今的主流Windows操做系統,存在着兩個統一的圖形接口:GDI和XPS。GDI是從Windows 95開始就一直支持的通用圖形接口,包括最新的Windows 10。而XPS是從Windows Vista開始,微軟開發的另外一個通用圖形接口,其目的是爲了替換已經老舊的GDI。但肩負着代替GDI使命的XPS過了多年依然沒達成這一任務,也就形成了今天Windows系統裏面GDI和XPS共存並相互兼容的狀態。咱們會在後面詳細講解GDI的架構以及XPS的架構。在這裏點出主要是便於幫助咱們理解打印假脫機(Spooler)的架構。
由於GDI和XPS共存且相互兼容,因此在Windwos的現有模式下,Windows打印假脫機(Spooler)的架構有兩種:基於GDI的打印假脫機(Spooler)的架構和基於XPS的打印假脫機(Spooler)的架構。
咱們首先來看基於GDI的打印假脫機(Spooler)的架構。
GDI的打印假脫機(Spooler)主要組成結構以下圖所示:【https://msdn.microsoft.com/en-us/library/windows/hardware/ff551781(v=vs.85).aspx】
應用經過調用GDI函數來建立打印任務,經過調用Winspool.drv提供的API接口,將打印內容路由到PrintProvider中。PrintProvider負責管理本地打印和遠程打印,同時要管理打印任務堆裏的啓動、中止和枚舉打印隊列。
下面分別介紹這些組件:
應用
打印應用程序經過調用GDI函數建立一個打印做業。
GDI
GDI是Graphics DeviceInterface的縮寫,含義是圖形驅動程序接口,是Microsoft設計的一套API,是圖形用戶界面GUI系統的一個重要組成部分:爲 Win32應用程序提供與設備無關的圖形編程界面,包括:視頻顯示、打印機、畫圖儀和傳真機。圖形設備接口(GDI)包括用戶模式和內核模式組件。微軟把工做於用戶模式的 GDI 稱爲 Win32 GDI API,工做於內核模式的GDI稱爲GDI 圖形引擎。
在 Windows 操做系統下,絕大多數具有GUI(Graphics UserInterface)的應用程序都離不開GDI。利用GDI所提供的衆多函數能夠方便地在屏幕、打印機及其它輸出設備上輸出圖形、文本等。GDI的出現使程序員無需關心硬件設備及設備驅動就能夠將應用程序的輸出轉化爲硬件設備上的輸出,實現了程序開發者與硬件設備的隔離,大大方便了開發工做。
WINSPOOL.DRV
Windows的打印客戶端(winspool.drv)把打印的APl暴露給用戶應用程序,用戶應用程序用打印API來查詢打印機、打印任務、改變打印機設置、查詢打印機設置、加載打印機驅動程序用戶界面DLL來顯示打印機具體設置屬性頁和作一些其餘的事情。Windows的打印客戶端(winspool.drv)幫助GDI決定打印任務應該如何處理。對於通常的打印任務,GDI生成EMF文件並把它送到打印池客戶,而後打印客戶用遠程進程調用把打印任務發送給打印系統服務進程spoolsv.exe。
SPOOLSV.EXE
spoolsv.exe是後臺打印程序的API服務器。spoolsv.exe打印服務向打印客戶DLL導出RPC (遠程過程調用)接口,用戶應用程序能夠用Windows的打印客戶端(winspool.drv)管理打印機、打印機驅動程序和打印任務。spoolsv.exe打印服務自己是一個小的EXE文件(Spoolsv.exe)。它經過打印路由把大多數調用送到打印機提供者。
Spoolsv.exe打印服務隨着操做系統啓動而啓動。該模塊輸出一個RPC接口到後臺處理程序的Win32 API中的服務器端。Spoolsv.exe中的客戶包括WINSPOOL.DRV(本地)和Win32spl.dll(遠程)。該模塊實現一些API函數,但大多數功能的調用由所述路由(SPOOLSS.DLL)的裝置傳遞到打印提供着。
打印路由
打印路由SPOOLSS.DLL,顧名思義就是肯定打印提供者在哪兒以及這麼到它哪兒!咱們使用的打印機有多是本地打印機,也多是在網絡中的網絡打印機。Spoolsv.exe打印系統服務使用打印路由(spoolss. dlI)把打印任務提交給打印機提供者,打印機提供者知道該把打印任務送到哪裏。
打印路由(spoolss. dlI)的任務很是簡單:就是找出正確的打印機提供者,而後把信息發送過去。它藉助系統註冊表中打印機相關的設置,經過打印任務所帶的打印機名或者打印機句柄信息完成這一任務。
打印提供者(Print Provider)
打印提供者負責把打印任務分配給本地或遠程計算機。它也管理打印任務隊列操做,如啓動、中止和任務枚舉。與打印服務進程和打印路由不一樣,系統中能夠有不少打印提供者。
Windows操做系統自己內置有幾個打印提供者:
本地打印機提供者(localspl.dll)。處理本地打印任務或遠程客戶發送到本地機的打印任務。每項打印任務最終都由本地打印機提供者處理,它把打印任務送到打印處理器(後面解釋)。
網絡打印機提供者(win32spl. dll)。把打印任務發送到遠程的網絡打印服務器。
HTTP打印機提供者(inetpp.dll)。把打印任務經過HTTP發送到URL地址進行打印。
其中,硬件打印機的廠商好比HP等,可以用Windows NT的DDK來編寫它們本身的打印機提供者。
打印處理器【打印驅動程序】
在上述打印提供者裏面出現了一個新名稱:打印處理器!打印處理器是專門負責把打印任務的打印文件轉換爲打印機能夠識別的原數據格式。在這裏咱們又須要引伸出另外的一個話題:打印機控制語言或者說打印機指令集。就如同計算機的硬盤同樣,應用程序須要對硬盤讀寫一個數據,須要將其請求發送給操做系統,操做系統會將其轉發給硬盤的SCSI控制器,硬盤的SCSI控制器將應用程序鎖請求的數據轉換爲硬盤可以理解的SCSI語言或者SCSI指令,而後發送到硬盤執行。
同理,在這裏這個打印處理器就相似於硬盤的SCSI控制器。所不一樣的是,硬盤的SCSI控制器是驅動程序加硬件芯片,也就是軟硬一體,而打印機的這個打印處理器,則是經過Windows的驅動程序來完成的,是一個純軟件的操做,所以在純粹的Windows的EMF格式下的光柵打印,會對系統的資源佔用較高。
在打印機市場,使用最廣的打印機指令有:ESC、PCL、PostScdpt指令。其中PCL、PostScdpt指令也被稱爲頁面描述語言(PDL,Page DescriptionalLanguage),ESC指令也被稱之爲嵌入式語言。這只是打印機語言其中的一種分類方法。這些都是打印機原始指令,大部分原始指令都來自於標準打印數據"EMF"的轉換,可是PCL6標準指令和PostScript指令不能經過轉換標準打印數據獲取,而是直接由打印驅動程序生成,故此PCL6指令打印和PostScript指令無需轉換指令而是直接將指令發送到打印設備,因此這兩種打印指令被爲原始打印也叫直接打印。其打印的數據不通過驅動程序的打印處理器進行轉換,而是直接發送到打印機,由打印機設備本身解析這些數據並打印。顯而易見這來兩種打印機語言打印效率就比較高。針對這些打印機語言的介紹咱們後面再說。
打印監視器
Windows支持兩種類型的打印監視器:語言監視器和端口監視器。在上述Windows的架構體系中,咱們能夠看到,打印假脫機程序還包含有一些打印的監視器。打印監視器負責把原始打印數據從打印服務引到正確的端口驅動程序上。
語言監視器,這裏的語言是指打印機固件能理解的各類打印機任務語言,如PCL。語言監視器的主要目的是經過雙向通訊電纜,在打印服務進程和打印機之間提供全雙工的通訊信道。計算機到打印機的數據管道主要用於把打印數據送到打印機,打印機到計算機的返回管道用於提供反饋信息。語言監視器的第二個目的是在打印機數據流中插入控制命令。
而端口監視器則是在打印服務進程和內核模式端口驅動程序之間提供通訊途徑,該驅動程序直接存取打印機連接的硬件的I/O端口。端口監視器是不能直接對硬件操做。它使用經常使用的文件 API同內核中的驅動程序通訊。端口監視器也負責管理邏輯打印機端口,例如本地計算機的全部COM 和LPT端口。
上述大概說明了基於GDI的打印假脫機(Spooler)主要組成結構。而基於XPS的打印假脫機(Spooler)又是如何的一個組成結構呢?
其實對於XPS的打印假脫機來講,和GDI的惟一區別就是GDI圖形接口換成了XPS圖形接口。在Windows中,程序員所開發的圖形應用程序,要麼採用GDI的圖形接口開進行開發,要麼採用WPF開發框架,WPF(Windows PresentationFoundation)是 Windows Vista中引入的新的用戶界面開發框架, 可提供更加絢麗的用戶交互界面.,WPF應用程序僅支持基於 XPS 的打印接口。也就是說,實際上是Windows 7以及以後的版本中,大部分新開發的應用程序都是基於WPF開發的,其調用的也是XPS接口。所以對於GDI或XPS來講,是GDI的應用程序就調用GDI的打印接口,是XPS的應用程序就調用XPS的打印接口。同時兩者又是能夠相互兼容和相互轉換的。
上述所說,Windows引入新的開發框架WPF和新的打印架構XPS,同時爲了兼容GDI,也分別作了兼容。那麼微軟是若是將XPS和GDI進行兼容的呢?
微軟爲了作到GDI和XPS的兼容,分別爲GDI和XPS提供了不一樣的打印路徑:GDI 打印路徑和 XPS 打印路徑以及兩個額外的轉換路徑。
兩個主要的打印路徑是:
GDI打印路徑(相似於Windows Server 2003的打印路徑)。該路徑也稱爲Win32的打印路徑,並由GDI API中Win32應用程序發起。
XPS打印路徑。此路徑起源於Windows PresentationFoundation (WPF)應用程序或XPSAPI的直接調用。
兩個轉換選項是:
GDI到XPS轉換(MXDC)。
XPS到GDI轉換(XGC)。
下圖顯示的GDI和XPS的不一樣打印路徑和轉換選項。