我試圖創造通過網絡接收打印作業C#中的「虛擬打印機」的應用,分析了某些信息的原始打印數據,然後將文檔保存到數據庫中。以下類的修改版本正在爲postscript打印作業(它將輸入數據保存到有效的.prn文件,就像打印機被設置爲打印到「FILE:」端口一樣)。當我嘗試捕獲時。來自Microsoft XPS Document Writer的XPS文檔雖然無法打開文檔。如果擴展名已重命名,則有效的XPS文件也應該是有效的ZIP文件,並且這也不起作用。當我將相同的文檔打印到FILE:端口,然後打印到我的應用程序時,並且我比較了Notepad ++中的結果時,數據長度有5個字符的差異,但看起來相同(它不是明文的,所以它是很難看,但前幾個字符和最後幾個字符看起來是相同的)。該文件保存「正常」的方式工作正常,但我的代碼生成的文件沒有。接收的XPS文件通過TcpClient的腐敗
更廣泛地說,我試圖通過TCP端口接收任意數據,並將其寫入文件。我的解決方案是「關閉」,但無法正常工作。我不知道XPS使用的是什麼類型的編碼,但是我使用ASCII作爲postscript,並且我已經嘗試過使用ASCII和UTF8編碼這個XPS版本。
任何幫助,非常感謝!這裏是我的代碼的相關部分:
class XPSListener
{
private TcpListener tcpListener;
private Thread listenThread;
private string instanceName = "";
private string fileShare = (Settings.Default.SharedPath.Substring(Settings.Default.SharedPath.Length - 1) == @"\") ? Settings.Default.SharedPath : Settings.Default.SharedPath + @"\"; // use SharedPath setting value - append backslash if it isn't already there.
public XPSListener(string initInstanceName, Int32 initPort)
{
this.instanceName = initInstanceName;
this.tcpListener = new TcpListener(IPAddress.Any, initPort);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
try
{
this.tcpListener.Start();
}
catch (Exception e)
{
MessageBox.Show("Socket Error 1 - " + e.StackTrace);
}
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(AcceptXPSData));
clientThread.Start(client);
}
}
private void AcceptXPSData(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
string tempFilePath = fileShare + "XPStemp_" + instanceName + ".oxps";
byte[] message = new byte[65536];
int bytesRead;
string input;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 65536);
Debug.WriteLine("Bytes read: " + bytesRead.ToString());
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
if (instanceName != "DontPrint")
{
Debug.WriteLine(instanceName + " Receiving Data");
//ASCIIEncoding encoder = new ASCIIEncoding();
UTF8Encoding encoder = new UTF8Encoding();
using (FileStream fs = new FileStream(tempFilePath, FileMode.Append, FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(fs))
{
input = encoder.GetString(message, 0, bytesRead);
sw.Write(input);
// first capture this input and write it to an xps file. This file can be converted to PDF at a later time by Ghostscript
// but we will still have access to the temp file for parsing purposes.
}
}
}
}
tcpClient.Close();
// processXPS();
}
@PeterDuniho - 我使用微軟XPS Document Writer的打印驅動程序,只是想使用不同的端口,以將結果發送到我的應用程序,而不是提示用戶保存到硬盤驅動器。其原因是自動化文件命名和存儲的方式。如果每次用戶輸入錯誤時文件都會丟失,這將是一場噩夢。 – 2014-12-10 22:57:03
那麼,您可以使用Visual Studio中的二進制編輯器來查看文件之間的_precise_差異。我仍然不明白'TcpClient'是如何涉及到的,但它不會破壞你的數據,我可以告訴你很多。你沒有正確地使用它 - 沒有理由相信只要對Read()進行一次調用就可以接收到整個文件的數據。重新編碼:如果您只是將數據寫入文件,則根本不要解釋它......只需將字節直接寫入文件即可。 XML(以及XPS)使用UTF8,但在這裏看起來並不重要。 – 2014-12-10 23:06:04
我不是責怪TCPClient,我只是有一個錯誤。 Read()在一個循環中 - 它填充一個緩衝區,然後附加到文件,直到沒有更多數據進入爲止。代碼的調試結果爲「Bytes Read:65536 Bytes Read:65536 Bytes Read:45888 Bytes Read:0 「 - 將緩衝區填充兩次,然後讀取剩餘的45888字節。這總計172.8 kb,這是我「打印以正常方式打印」時獲得的文件的確切大小,但有趣的是,我的程序生成的文件爲310kb,而不是調試所指示的173 KB。二進制編輯器顯示「類似的數據」,但在我的很多額外的垃圾。 – 2014-12-10 23:39:31