问题
I have currently-working code which sends raw data to a printer by writing a temporary file, then using File.Copy()
to send it to the printer. File.Copy()
supports both local ports, like LPT1
and shared printers like \\FRONTCOUNTER\LabelPrinter
.
However, now I'm trying to get it working with a printer that's directly on the network: 192.168.2.100
, and I can't figure out the format to use.
File.Copy(filename, @"LPT1", true); // Works, on the FRONTCOUNTER computer
File.Copy(filename, @"\\FRONTCOUNTER\LabelPrinter", true); // Works from any computer
File.Copy(filename, @"\\192.168.2.100", true); // New printer, Does not work
I know it's possible to "Add a printer" from each computer, but I'm hoping to avoid that - the second line of code above works from any computer on the network automatically, with no configuration required. I also know it's possible to P/Invoke the windows print spooler, and if that's my only option I may take it, but that's much more code overhead than I'd like to have.
Ideally, someone will have either a way to make File.Copy()
work or a similar C# statement which will accept a network IP.
回答1:
You can use sockets and send the data straight to that IP address. Should pretty much be the same as File.Copy
. I just tried it out and that worked.
I just sent some text but here is the code that I used
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.NoDelay = true;
IPAddress ip = IPAddress.Parse("192.168.192.6");
IPEndPoint ipep = new IPEndPoint(ip, 9100);
clientSocket.Connect(ipep);
byte[] fileBytes = File.ReadAllBytes("test.txt");
clientSocket.Send(fileBytes);
clientSocket.Close();
回答2:
try this code:
public class PrintHelper
{
private readonly IPAddress PrinterIPAddress;
private readonly byte[] FileData;
private readonly int PortNumber;
private ManualResetEvent connectDoneEvent { get; set; }
private ManualResetEvent sendDoneEvent { get; set; }
public PrintHelper(byte[] fileData, string printerIPAddress, int portNumber = 9100)
{
FileData = fileData;
PortNumber = portNumber;
if (!IPAddress.TryParse(printerIPAddress, out PrinterIPAddress))
throw new Exception("Wrong IP Address!");
}
public PrintHelper(byte[] fileData, IPAddress printerIPAddress, int portNumber = 9100)
{
FileData = fileData;
PortNumber = portNumber;
PrinterIPAddress = printerIPAddress;
}
/// <inheritDoc />
public bool PrintData()
{
//this line is Optional for checking before send data
if (!NetworkHelper.CheckIPAddressAndPortNumber(PrinterIPAddress, PortNumber))
return false;
IPEndPoint remoteEP = new IPEndPoint(PrinterIPAddress, PortNumber);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.NoDelay = true;
connectDoneEvent = new ManualResetEvent(false);
sendDoneEvent = new ManualResetEvent(false);
try
{
client.BeginConnect(remoteEP, new AsyncCallback(connectCallback), client);
connectDoneEvent.WaitOne();
client.BeginSend(FileData, 0, FileData.Length, 0, new AsyncCallback(sendCallback), client);
sendDoneEvent.WaitOne();
return true;
}
catch
{
return false;
}
finally
{
// Shutdown the client
this.shutDownClient(client);
}
}
private void connectCallback(IAsyncResult ar)
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
// Signal that the connection has been made.
connectDoneEvent.Set();
}
private void sendCallback(IAsyncResult ar)
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
// Signal that all bytes have been sent.
sendDoneEvent.Set();
}
private void shutDownClient(Socket client)
{
client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
Network Helper class:
public static class NetworkHelper
{
public static bool CheckIPAddressAndPortNumber(IPAddress ipAddress, int portNumber)
{
return PingIPAddress(ipAddress) && CheckPortNumber(ipAddress, portNumber);
}
public static bool PingIPAddress(IPAddress iPAddress)
{
var ping = new Ping();
PingReply pingReply = ping.Send(iPAddress);
if (pingReply.Status == IPStatus.Success)
{
//Server is alive
return true;
}
else
return false;
}
public static bool CheckPortNumber(IPAddress iPAddress, int portNumber)
{
var retVal = false;
try
{
using (TcpClient tcpClient = new TcpClient())
{
tcpClient.Connect(iPAddress, portNumber);
retVal = tcpClient.Connected;
tcpClient.Close();
}
return retVal;
}
catch (Exception)
{
return retVal;
}
}
}
来源:https://stackoverflow.com/questions/18704839/send-text-file-directly-to-network-printer