亚洲韩日午夜视频,欧美日韩在线精品一区二区三区,韩国超清无码一区二区三区,亚洲国产成人影院播放,久草新在线,在线看片AV色

您好,歡迎來(lái)到思海網(wǎng)絡(luò),我們將竭誠(chéng)為您提供優(yōu)質(zhì)的服務(wù)! 誠(chéng)征網(wǎng)絡(luò)推廣 | 網(wǎng)站備案 | 幫助中心 | 軟件下載 | 購(gòu)買(mǎi)流程 | 付款方式 | 聯(lián)系我們 [ 會(huì)員登錄/注冊(cè) ]
促銷(xiāo)推廣
客服中心
業(yè)務(wù)咨詢(xún)
有事點(diǎn)擊這里…  531199185
有事點(diǎn)擊這里…  61352289
點(diǎn)擊這里給我發(fā)消息  81721488
有事點(diǎn)擊這里…  376585780
有事點(diǎn)擊這里…  872642803
有事點(diǎn)擊這里…  459248018
有事點(diǎn)擊這里…  61352288
有事點(diǎn)擊這里…  380791050
技術(shù)支持
有事點(diǎn)擊這里…  714236853
有事點(diǎn)擊這里…  719304487
有事點(diǎn)擊這里…  1208894568
有事點(diǎn)擊這里…  61352289
在線客服
有事點(diǎn)擊這里…  531199185
有事點(diǎn)擊這里…  61352288
有事點(diǎn)擊這里…  983054746
有事點(diǎn)擊這里…  893984210
當(dāng)前位置:首頁(yè) >> 技術(shù)文章 >> 文章瀏覽
技術(shù)文章

Windows 打印管理在Linux 平臺(tái)實(shí)現(xiàn)

添加時(shí)間:2011-5-27  添加: admin 
本文介紹了一種在 Linux 平臺(tái)上實(shí)現(xiàn) Windows 打印機(jī)管理的移植方法及具體實(shí)現(xiàn)細(xì)節(jié)。通過(guò)本文,讀者可以了解相關(guān)技術(shù),并把這些技術(shù)直接應(yīng)用到實(shí)際軟件開(kāi)發(fā)中。

1.理解 Windows 打印機(jī)管理和 Linux 打印機(jī)管理

    Windows 平臺(tái)提供了非常簡(jiǎn)單而且完善的打印機(jī)管理系統(tǒng)。在 Windows 編程中,打印功能被融入了 GDI (Graphic Device Interface)模塊。在 GDI 模塊中,程序員只要調(diào)用 EnumPrinters() 等 APIs 就可以輕松獲取打印機(jī)信息。Windows 的這種成熟打印管理機(jī)制很大程度上得益于打印機(jī)供應(yīng)商所提供的完善的打印機(jī)驅(qū)動(dòng)。Windows 的打印機(jī)驅(qū)動(dòng)屏蔽了打印機(jī)的具體打印實(shí)現(xiàn)細(xì)節(jié),同時(shí)為上層調(diào)用提供了簡(jiǎn)單的 API 接口。

    與 Windows 平臺(tái)相反,打印機(jī)管理機(jī)制在 Linux 平臺(tái)上從產(chǎn)生到成熟卻經(jīng)過(guò)了一個(gè)漫長(zhǎng)的過(guò)程。Linux 打印系統(tǒng)最早源于 UNIX 打印系統(tǒng),但 UNIX 系統(tǒng)卻一直缺乏統(tǒng)一的標(biāo)準(zhǔn)接口。由于歷史原因,不同 UNIX 平臺(tái)使用著不同的打印系統(tǒng)。在各種 UNIX 打印解決方案中,最流行的是 Berkeley 打印系統(tǒng)和 System V 打印系統(tǒng)。一方面,不同打印系統(tǒng)需要不一樣的打印驅(qū)動(dòng)支持;另一方面,UNIX 只擁有相對(duì)較小的客戶群。這些因素使得很多打印機(jī)供應(yīng)商完全放棄了對(duì) UNIX 平臺(tái)的支持。統(tǒng)一打印接口的缺乏和底層驅(qū)動(dòng)的不完善使打印在很長(zhǎng)一段時(shí)間內(nèi)成為了 Linux 平臺(tái)的一大功能漏洞。

    最終 CUPS (Common UNIX Printing System)的出現(xiàn)解決了上述窘境。CUPS 是UNIX/Linux 上通用的打印系統(tǒng)。CUPS 提供了一套 CUPS API 來(lái)完成 UNIX/Linux系統(tǒng)和打印機(jī)之間的交互。例如,用戶可以通過(guò) CUPS 獲取打印機(jī)的信息,也可以通過(guò) CUPS 設(shè)置打印機(jī)。CUPS 提供了對(duì) Berkeley 和 System V 打印命令的支持,這種兼容性使得之前的系統(tǒng)不用進(jìn)行大規(guī)模修改就可被延續(xù)使用。同時(shí),CUPS 還提供一系列模塊化的過(guò)濾接口。通過(guò)這些接口,打印機(jī)提供商只需要開(kāi)發(fā)一個(gè)驅(qū)動(dòng)程序就可以滿足所有平臺(tái)的需求。至今為止,CUPS 已被所有 UNIX 和 Linux 平臺(tái)所支持。

2.打印機(jī)管理移植架構(gòu)

    打印機(jī)管理移植是應(yīng)用程序跨平臺(tái)移植的重要組成部分。不同平臺(tái)所支持的打印接口是不同的,因此移植的核心就是實(shí)現(xiàn)平臺(tái)之間的打印機(jī)管理接口的轉(zhuǎn)換。下圖展示了打印機(jī)管理移植的架構(gòu)。

    Windows 提供了一系列 API 來(lái)獲取打印機(jī)信息。這些信息被封裝在預(yù)定義的Windows 標(biāo)準(zhǔn)結(jié)構(gòu)中,比如 DEVMODE,PRINTER_INFO_2,PRINTER_INFO_4 等等。Linux 使用 CUPS 來(lái)獲取打印機(jī)信息,這些信息被封裝在 cups_dest_t,ipp_attribute_t 等數(shù)據(jù)結(jié)構(gòu)中。只要正確獲取 Linux 平臺(tái)上打印機(jī)信息,并把它們轉(zhuǎn)化成 Windows 打印機(jī)數(shù)據(jù)結(jié)構(gòu),就可以完成打印機(jī)管理。

3.CUPS 基礎(chǔ)知識(shí)

    CUPS 是 UNIX/Linux 平臺(tái)上的打印系統(tǒng)。CUPS 的定義和實(shí)現(xiàn)是基于 IPP(Internet Printing Protocol)協(xié)議的。IPP 是通用的打印系統(tǒng)標(biāo)準(zhǔn),它的功能和操作被一系列RFC(Request for Comments)所詳細(xì)定義。這些具體功能和操作包括:建立 IPP請(qǐng)求,應(yīng)答 IPP 請(qǐng)求和設(shè)置 IPP 請(qǐng)求等等。和 IPP 相關(guān)的 RFC 包括 RFC1179,RFC2910,RFC2911,RFC3196 等等。在網(wǎng)絡(luò)協(xié)議中,IPP 位于 HTTP(Hyper-Text Transport Protocol)協(xié)議之上。因此以下代碼示例將涉及到很多 IPP 和 HTTP的系統(tǒng)調(diào)用,例如 ippAddString() 和 httpConnectEncrypt() 等等。此外,在UNIX/Linux 平臺(tái)上在使用 CUPS 之前要提前引入下列頭文件:


#include <cups/cups.h>#include <cups/language.h>#include <cups/http.h>#include <cups/ipp.h>

    有了上述 CUPS 基礎(chǔ)知識(shí),下文將舉例說(shuō)明使用 CUPS 實(shí)現(xiàn)打印機(jī)管理移植的技術(shù)細(xì)節(jié)。

4.獲取打印機(jī)數(shù)量

    Windows 通過(guò) API EnumPrinters() 的返回參數(shù) pcReturned 來(lái)獲取系統(tǒng)的打印機(jī)數(shù)量。Windows 程序的具體實(shí)現(xiàn)如下所示:


int n_PrinterCount;EnumPrinters( , , , , , , &n_PrinterCount);

    在 Linux 中,CUPS 函數(shù) cupsGetDests() 可實(shí)現(xiàn)同樣的功能。需要注意的是,在調(diào)用結(jié)束后,調(diào)用者需要使用 cupsFreeDests() 來(lái)釋放內(nèi)存。


    cups_dest_t *dests;    int n_PrinterCount = cupsGetDests( &dests );    cupsFreeDests(count, dests);    

5.獲取打印機(jī)名稱(chēng),打印機(jī)端口和打印機(jī)型號(hào)

    Windows使用API EnumPrinters() 來(lái)獲取打印機(jī)名稱(chēng),打印機(jī)端口和打印機(jī)型號(hào)。詳情請(qǐng)參考Windows MSDN。在Linux平臺(tái)上,CUPS可實(shí)現(xiàn)同樣的功能。具體實(shí)現(xiàn)流程如下圖所示:


圖2 獲取打印機(jī)信息(名稱(chēng),端口,型號(hào))流程
 

5.1建立 HTTP 連接

    使用 CUPS 獲取打印機(jī)名稱(chēng),打印機(jī)端口和打印機(jī)型號(hào)信息首先需要開(kāi)啟 IPP 和HTTP 服務(wù)。開(kāi)啟服務(wù)的第一步是建立一個(gè) HTTP 連接來(lái)和 CUPS 服務(wù)器取得聯(lián)系。在下面的代碼中,cupsServer() 將返回指向默認(rèn) CUPS 服務(wù)器名稱(chēng)的指針;ippPort() 將返回 IPP 請(qǐng)求的默認(rèn)端口號(hào);cupsEncryption() 將返回當(dāng)前 CUPS 請(qǐng)求的默認(rèn)加密設(shè)置。將這些返回值作為參數(shù)傳遞給函數(shù) httpConnectEncrypt() 就可以建立一個(gè) HTTP 連接。如果 HTTP 連接建立成功,即 httpConnectEncrypt() 的返回值pHTTPConnection 有效,那么就可以基于這個(gè)連接進(jìn)行下一步 IPP 請(qǐng)求。


        http_t *pHTTPConnection = httpConnectEncrypt( cupsServer(),                                             ippPort(),                                             cupsEncryption() );    if (!pHTTPConnection)    {        g_print("Cannot connect to CUPS server\n");        return 0;    }    

5.2建立 IPP 請(qǐng)求

    建立一個(gè)新的 IPP 請(qǐng)求是通過(guò) IPP 調(diào)用 ippNew() 來(lái)實(shí)現(xiàn)的。在此,operation_id 被設(shè)置為 CUPS_GET_PRINTERS,其語(yǔ)義是當(dāng)前 IPP 請(qǐng)求要獲取和打印機(jī)相關(guān)的信息。同時(shí),request_id 被設(shè)置為 1,這是 IPP 協(xié)議所規(guī)定的。


        ipp_t *pIPPReq = ippNew();    pIPPReq->request.op.operation_id = CUPS_GET_PRINTERS;    pIPPReq->request.op.request_id = 1;

5.3設(shè)置 IPP 請(qǐng)求

    以下是進(jìn)一步設(shè)置當(dāng)前 IPP 請(qǐng)求 pIPPReq 的細(xì)節(jié)。需要指出的是,在和 CUPS 服務(wù)器進(jìn)行交互的過(guò)程中,很多信息是通過(guò)字符串來(lái)傳遞的。這就涉及到了文字語(yǔ)言編碼表示的問(wèn)題。函數(shù) cupsLangDefault() 就是用來(lái)獲取 CUPS 服務(wù)器的默認(rèn)語(yǔ)言設(shè)置。cupsLangDefault() 的返回值 pDefLang 還將作為參數(shù)傳遞給其它函數(shù)來(lái)完成對(duì) IPP 請(qǐng)求的進(jìn)一步設(shè)置。

    根據(jù) IPP 協(xié)議,對(duì) IPP 請(qǐng)求的設(shè)置要從設(shè)置參數(shù) "attributes-charset"(字符集)和"attributes-natural-language"(自然語(yǔ)言)開(kāi)始。下列代碼分別用系統(tǒng)默認(rèn)字符集和CUPS 默認(rèn)語(yǔ)言來(lái)設(shè)置這兩個(gè)參數(shù)。完成這兩項(xiàng)規(guī)定設(shè)置后,用戶就可以根據(jù)需求對(duì)需要的信息提出請(qǐng)求。此處需要獲得的信息是打印機(jī)名稱(chēng),端口號(hào)和打印機(jī)型號(hào)。在 IPP 協(xié)議中,這三項(xiàng)對(duì)應(yīng)的IPP請(qǐng)求關(guān)鍵字分別是 "printer-name", "device-uri" 和 "printer-make-and-model"。下列代碼定義了數(shù)組 pReqAttrs 來(lái)存儲(chǔ)上述關(guān)鍵字,然后通過(guò)請(qǐng)求參數(shù) "requested-attributes" 來(lái)設(shè)置這些 IPP 請(qǐng)求。


                      cups_lang_t *pDefLang = cupsLangDefault();    if (!pDefLang)    {        g_print("Cannot get default language\n");        return 0;    }    ippAddString(pIPPReq,                 IPP_TAG_OPERATION,                 IPP_TAG_CHARSET,                 "attributes-charset",                 NULL,                 cupsLangEncoding(pDefLang));    ippAddString(pIPPReq,                 IPP_TAG_OPERATION,                 IPP_TAG_LANGUAGE,                 "attributes-natural-language",                 NULL,                 pDefLang->language);static const char *pReqAttrs[] = {"printer-name", "device-uri","printer-make-and-model"};    ippAddStrings(pIPPReq,                  IPP_TAG_OPERATION,                  IPP_TAG_KEYWORD,                  "requested-attributes",                  3,                     NULL,                  pReqAttrs);                  

5.4發(fā)送 IPP 請(qǐng)求

    設(shè)置好 IPP 請(qǐng)求之后,通過(guò)函數(shù) cupsDoRequest() 就可以把指定IPP請(qǐng)求發(fā)送到服務(wù)器端。如果請(qǐng)求發(fā)送成功,那么請(qǐng)求發(fā)送方將得到有效的IPP應(yīng)答pIPPRes。需要指出的是,即使 IPP 應(yīng)答有效,也并不意味著所有 IPP 請(qǐng)求的內(nèi)容都得到了正確的回復(fù)。還需要進(jìn)一步檢查 IPP 應(yīng)答的狀態(tài)代碼 "request.status.status_code" 來(lái)核實(shí)反饋信息的有效性。


        ipp_t *pIPPRes = cupsDoRequest(pHTTPConnection, pIPPReq, "/");    if (!pIPPRes)    {        g_print("No response from CUPS server\n");        return 0;    }    if (pIPPRes->request.status.status_code > IPP_OK_CONFLICT)    {        printf("IPP Error: %s\n", ippErrorString(pIPPRes->request.status.status_code));        ippDelete(pIPPRes);        return 0;    }

5.5獲取 IPP 應(yīng)答

    如果上述操作都成功返回,就可以進(jìn)一步從 pIPPRes 結(jié)構(gòu)中提取感興趣的信息。在下列代碼中,變量 pPrinterName,pPortName 和 pPrinterModel 分別用來(lái)存儲(chǔ)打印機(jī)名稱(chēng),打印機(jī)端口號(hào)和打印機(jī)的類(lèi)型信息。通過(guò)依次枚舉 IPP 應(yīng)答 pIPPRes 來(lái)尋找屬性 pAttr->name 為 "printer-name" 或 "device-uri" 或 "printer-make-and-model" 的分量,就可以得到上述信息。


        char *pPrinterName = NULL;    char *pPortName = NULL;    char *pPrinterModel = NULL;    for (ipp_attribute_t *pAttr = pIPPRes->attrs; pAttr != NULL; pAttr =pAttr->next)    {        if (pAttr->group_tag == IPP_TAG_PRINTER)        {            if (0 == strcmp(pAttr->name, "printer-name"))                pPrinterName = pAttr->values->string.text;            if (0 == strcmp(pAttr->name, "device-uri"))                pPortName = pAttr->values->string.text;            if (0 == strcmp(pAttr->name, "printer-make-and-model"))                pPrinterModel = pAttr->values->string.text;        }    }    

5.6釋放內(nèi)存

    最后,需要釋放相關(guān)內(nèi)存以免內(nèi)存泄露:


        httpClose(pHTTPConnection);    ippDelete(pIPPRes);    

6字符編碼轉(zhuǎn)換

    在實(shí)現(xiàn)打印機(jī)管理的移植過(guò)程中,還需要特別注意字符編碼轉(zhuǎn)換的問(wèn)題。當(dāng)然,字符編碼問(wèn)題不僅僅局限于本文所探討的范疇,它同時(shí)還是所有應(yīng)用程序移植都需要特別關(guān)注的技術(shù)細(xì)節(jié)。以本文為例,在 Linux 上獲取的字符串,比如打印機(jī)名稱(chēng),通常是 UTF-8(Unicode Transformation Format) 編碼的。而 Windows 應(yīng)用程序并不使用 UTF-8 編碼。由于歷史原因,Windows 程序或使用 ANSI 編碼方式,或使用UTF-16 編碼方式。因此,從 CUPS 獲取的字符串還需要根據(jù)程序運(yùn)行環(huán)境進(jìn)行編碼轉(zhuǎn)換,之后才能被 Windows 應(yīng)用程序使用。字符編碼轉(zhuǎn)換可以使用 IBM ICU(International Components for Unicode)來(lái)完成。詳情請(qǐng)參考 http://www-306.ibm.com/software/globalization/icu/index.jsp

7.結(jié)束語(yǔ)

    移植是一項(xiàng)實(shí)現(xiàn)應(yīng)用程序跨平臺(tái)運(yùn)行的核心技術(shù)。本文重點(diǎn)闡述了 Windows 打印機(jī)管理系統(tǒng)在 Linux 平臺(tái)上的移植技術(shù)。通過(guò)具體舉例,本文詳細(xì)分析了打印機(jī)管理在 Linux 平臺(tái)上的移植細(xì)節(jié)。本章涉及的移植架構(gòu)和移植概念不僅僅局限于打印機(jī)管理移植。這些概念和思想也是所有應(yīng)用程序所通用的。應(yīng)用程序跨平臺(tái)移植已經(jīng)在很多軟件中被應(yīng)用。實(shí)現(xiàn)應(yīng)用程序在不同平臺(tái)上無(wú)縫隙的運(yùn)行操作也將是每位移植技術(shù)人員的共同目標(biāo)。



 

參考資料

  1. "CUPS Software Programmers Manual", Easy Software Products, Copyright 1997-2004
  2. "CUPS Implementation of IPP", Easy Software Products, Copyright 1997-2004
  3. RFC2910 "Internet Printing Protocol/1.1: Encoding and Transport", 2000
  4. RFC2911 "Internet Printing Protocol/1.1: Model and Semantics", 2000
  5. RFC3196 "Internet Printing Protocol/1.1: Implementor's Guide", 2001
  6. MSDN: Microsoft Developer Network
  7. http://www-306.ibm.com/software/globalization/icu/index.jsp

關(guān)鍵字:管理、平臺(tái)、打印

分享到:

頂部 】 【 關(guān)閉
版權(quán)所有:佛山思海電腦網(wǎng)絡(luò)有限公司 ©1998-2024 All Rights Reserved.
聯(lián)系電話:(0757)22630313、22633833
中華人民共和國(guó)增值電信業(yè)務(wù)經(jīng)營(yíng)許可證: 粵B1.B2-20030321 備案號(hào):粵B2-20030321-1
網(wǎng)站公安備案編號(hào):44060602000007 交互式欄目專(zhuān)項(xiàng)備案編號(hào):200303DD003  
察察 工商 網(wǎng)安 舉報(bào)有獎(jiǎng)  警警  手機(jī)打開(kāi)網(wǎng)站