2011年4月30日 星期六

Crystal Reports與ASP.NET網路送印問題處理與分享

        最近接到一個需求,當使用者希望將原本的報表(Crystal Reports)直接送印到報表主機上的某一台印表機時,該如何進行,基本上程式不困難,但因為這個問題主要由是作業系統造成(Q152451 、 Q184291),所以需進行相關的修正後,程式的寫法也需要調整過才能進行,所以我在這整理一下我的作法並分享出來。

         很多人會問為何不要當報表打開後再直接手動按列印即可,何必要這個功能,但是你想如何有一個單位每天有幾百張報表要印,每一張都要等個10幾秒,那直接送印是不是就可以當掉許多的時間,而目前大部份的使用者在處理這個問題上,大部份都是在客戶端也需要裝上相對的驅動程式,才可以進行直接送印,但是這樣一來在日後部署上就會有問題,而且維護成本也會相對的變重。

設定的步驟如下:

1、先設定IIS的執行身份,這個問題主要是由於當進行網路列印時,Windows並不會指定帳號,所以必須指定固定帳號,並設定印表機的執行身份與權限。
設定伺服器端列印

存取 Machine.config 檔,其預設位置如下:
C:\WINNT\Microsoft.NET\Framework\<VersionNumber>\CONFIG\

<VersionNumber> 是安裝在電腦上的 .NET Framework 的版本。帳戶設定是位於這個檔案的 <ProcessModel> 標記內。帳戶的預設值是:userName="machine" password="AutoGenerate"

請編輯 Machine.config 檔中的組態設定。將預設值變更為:
userName="SYSTEM" password="AutoGenerate"


儲存檔案。
現在就能夠將伺服器上的列印權限賦與本機 SYSTEM 帳戶。

如果印表機是網路印表機,請將此網路印表機公開給本機 SYSTEM 帳戶。
當印表機安裝在電腦上時,這個印表機的設定會儲存在登錄中;而登錄是位於 HKEY_CURRENT_USER 登錄群組 (登錄檔) 之下。IIS 處理序永遠不會使用這個登錄群組,因為它一定是在本機系統帳戶的內容下執行,並且無法以「目前使用者」的身份登入伺服器。根據預設,SYSTEM 帳戶在登錄中並沒有設定任何印表機。有兩篇 Microsoft Knowledge Base 文件,Q152451Q184291 會說明如何將印表機設定公開給 System 帳戶。這兩篇文件都會要求您編輯 Web 伺服器上的登錄,並且將印表機設定從 HKEY_CURRENT_USER 群組複製到 HKEY_USERS/.DEFAULT 群組。

2、設定指定帳號後,就需要透過設定登錄檔的方式指定System帳號的可用印表機有那些。

您可以設定 SYSTEM 帳戶如果要解決這個問題的印表機。 若要設定 SYSTEM 帳戶的印表機,執行下列步驟:
這個方法會要求您修改使用 「 登錄編輯程式 」 登錄。
警告: 不當使用 「 登錄編輯器 」 可能會導致嚴重的全系統的問題,必須重新安裝 Windows 修正它們。 Microsoft 無法保證任何因使用登錄編輯程式所造成的問題可以獲得解決。使用此工具,請自行負擔相關的風險。
確定您目前登入伺服器的使用者具有您想要安裝的印表機。
啟動登錄編輯程式 (Regedit.exe)。
選取下列機碼:
      HKEY_CURRENT_USER
         \Software\Microsoft\Windows NT\Current Version\Devices

按一下 [登錄] 功能表的 [匯出登錄檔案]。
在 [檔案名稱] 文字方塊中,輸入 c:\Devices.reg。
選取下列機碼:
      HKEY_CURRENT_USER
         \Software\Microsoft\Windows NT\Current Version\PrinterPorts

按一下 [登錄] 功能表的 [匯出登錄檔案]。
在 [檔案名稱] 文字方塊中,輸入 c:\PrinterPorts.reg。
選取下列機碼:
      HKEY_CURRENT_USER
         \Software\Microsoft\Windows NT\Current Version\Windows

按一下 [登錄] 功能表的 [匯出登錄檔案]。
在 [檔案名稱] 文字方塊中,輸入 c:\Windows.reg。
從 [開始] 按鈕選取 [執行]。在執行] 對話方塊中鍵入 「 記事本 」 Devices.reg,「 記事本 」 開啟 Devices.reg。
文字 HKEY_CURRENT_USER 取代 HKEY_USERS\.DEFAULT
儲存檔案。然後匯入登錄連按兩下檔案,在 [檔案總管] 中。
對 PrinterPorts.reg 和 Windows.reg 重複執行修改後再匯入的步驟即可。
這些步驟僅適用於本機印表機。

若要以便 IIS 使用 SYSTEM 帳戶來列舉網路印表機請依照下列步驟執行。
附註網路服務帳戶下執行處理程序,明確的權限到新建立的登錄需要。
請確定您目前登入伺服器以使用者身分已安裝的所需的網路印表機。
啟動 「 登錄編輯程式 」。
按一下下列機碼:
HKEY_CURRENT_USER\Printers\Connections
在 [登錄] 功能表上按一下 [匯出登錄檔案]。
在 [檔案名稱] 方塊中,輸入 c:\printconns.reg。
在 「 記事本 」 開啟 printconns.reg 檔案,請按一下 [開始]、 按一下 [執行]、 在 [開啟] 方塊輸入 記事本 printconns.reg,然後按一下 [[確定]]。
取代文字 HKEY_USERS\.DEFAULT HKEY_CURRENT_USER 文字。
儲存檔案。
將檔案匯入到登錄,按兩下在 [檔案總管] 中的檔案。
重新啟動列印多工緩衝處理器 」 服務。


3、當瞬間的列印排程過多時,可能也會出現相同的錯誤訊息,所以可以透過修改登錄檔的方式進行調整,並將原本預設值從75調整放大,藉以減少列印排程超過設定值而造成錯誤發生。

HKEY_LOCAL_MACHINE\SOFTWARE\Business Objects \Suite 11.x\Report Application Server\InprocServer\PrintJobLimit

4、設定System帳號可以存取相關的印表機。




5、當修改完上述的設定值之後,在程式進行直接列印的部份也需要進行調整,不可用ReportDocument.PrintOptions.PrinterName的方式來指定,必須用PrinterSettings的方式來進行印表機的設定,C#程式碼如下:

舊有寫法:

rptDoc.PrintOptions.PrinterName = printerSettings.PrinterName;


新的寫法:

PrinterSettings printerSettings = new PrinterSettings();
PageSettings pageSettings = new PageSettings();
rd.PrintOptions.CopyTo(printerSettings, pageSettings);
printerSettings.PrinterName = PrinterName;
printerSettings.PrintRange = PrintRange.AllPages;
printerSettings.Collate = false;
printerSettings.Copies = 1;
pageSettings.PrinterSettings = printerSettings;
rd.PrintToPrinter(printerSettings, pageSettings, false);


參考網址:
1、http://msdn.microsoft.com/zh-tw/library/aa290045(v=vs.71).aspx
2、http://support.microsoft.com/kb/184291

關鍵字:Q152451 、 Q184291、Crystal Reports、網路送印、IIS、Server Print、PrintJobLimit、C#

沒有留言:

張貼留言