最近做的xps文檔打印功能,絕對的一波三折,一開始開發的時候,始終用的是xps writer 虛擬打印機,測試的時候也是,一直沒有發現問題,但是真正到用戶使用的時候,接上正式打印機,打印時候沒有問題,一旦打印完成,再次進入打印winfrom的界面就花掉了,如下圖;
結果更換了多台電腦,win7、winxp都不行,然后就更換打印機,換了很多打印機也不行,自己寫了一個最小的打印的程序,發現打印以后還出現同樣的問題。
沒有辦法,試着去微軟的官方論壇上看看有沒有大牛能幫忙解決一下,結果還真有一個搭理我的,我發了一個測試的程序過去,人家說他們那邊沒有問題。我當時凌亂了,突然想到,這個會不會跟window語言有關系,結果下載了一個英文的語言包,把window修改成英語版就OK了。
不過,這樣的做法絕對是要被人唾棄的,我們的項目總不能讓用戶直接用英文windows吧。
解決的方法有兩個
1、 所有界面上的字體不用宋體(不保證圖片不花,沒有測試過),我們的項目這么大葯吧所有的界面都進行修改不可能。
2、 使用wpf單獨做一個進程,進行打印,打印的時候,由程序直接寫入到打印隊列中,不需要有任何的form交互即可。
這個地方有三個地方比較值得注意:
(1) winform開啟新進程,這個沒啥難度,唯一注意的是,如果需要傳遞參數的話,不能和程序名寫到一起
Process.Start("NewPrint.exe",”參數1”);
(2) wpf運行程序,獲取程序帶入參數值,通過重載OnStartup函數實現
protected override void OnStartup(StartupEventArgs e)
{
string IDCard = e.Args[0];
base.OnStartup(e);
}
(3) 將wpf文檔直接寫入打印機隊列里面,參照下文:
如何以編程的方式直接打印
http://msdn.microsoft.com/zh-cn/library/vstudio/aa969772(v=vs.90).aspx
我們就用了一個比較偷懶的辦法,代碼如下:

public class BatchXPSPrinter { public static void PrintXPS(object sender) { string strFilename = sender.ToString(); LocalPrintServer localPrintServer = new LocalPrintServer(); PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue(); bool tt = defaultPrintQueue.IsXpsDevice; FileInfo f = new FileInfo(strFilename); try { PrintSystemJobInfo xpsPrintJob = defaultPrintQueue.AddJob(f.Name, strFilename, false); } catch (PrintJobException e) { } } }
直接在進程里面調用:
string DocName="";
Thread printingThread = new Thread(new ParameterizedThreadStart(BatchXPSPrinter.PrintXPS)); printingThread.SetApartmentState(ApartmentState.STA); printingThread.Start(DocName); MessageBox.Show("打印完成");
通過在這次的問題解決的過程對我觸動比較深的幾點:
1、做程序的最好查谷歌。百度在技術領域的搜索真心不行,很多時候答非所問。技術類的文章不明白的單詞就那么幾個,看熟了就會了!
2、不要怕自己的英語水平爛,我的英語水平也爛,屬於初中畢業水平,但是就我這個初中水平,也能在國外論壇上提出問題,並且老外能看明白,並
能夠進行解答,說明一個問題,很多時候不需要那么多華麗的句型,只要說明白主要意思,哪怕全部都是this is ,that is ,都沒有關系。后面還有程序語句這種全球通用的代碼
來進行二次說明的!
3、微軟的東西不一定都是好的,如果真的遇到了實在解決不了的,干脆就繞過去!不過這點個人感覺java比微軟的可選擇性就多了!