C# 如何用C打印PCL文件?
我有一个PCL文件,我使用“打印到文件”生成 用C语言编程打印此文件的最佳方式是什么 当然,我正在打印的打印机支持PCL 我知道我可以通过从提示符调用来打印:C# 如何用C打印PCL文件?,c#,printing,printer-control-language,C#,Printing,Printer Control Language,我有一个PCL文件,我使用“打印到文件”生成 用C语言编程打印此文件的最佳方式是什么 当然,我正在打印的打印机支持PCL 我知道我可以通过从提示符调用来打印: copy filename.pcl //location/printername 所以我可以想象,我也可以使用copy以编程方式做同样的事情。。。我想知道是否有一种更干净的方法可以做到这一点,比如说使用PrintDocument 请注意,当我使用PrintDocument时: var pd = new PrintDocument
copy filename.pcl //location/printername
所以我可以想象,我也可以使用copy以编程方式做同样的事情。。。我想知道是否有一种更干净的方法可以做到这一点,比如说使用PrintDocument
请注意,当我使用PrintDocument时:
var pd = new PrintDocument
{
DocumentName = @"filename.pcl";
PrinterSettings = {PrinterName = @"\\location\printername"}
};
pd.Print();
我总是会打印一个空白页。,但我认为这很容易理解,可以将其应用到C语言中。否则,我很乐意帮助您解决任何有问题的部分
如果打印机在网络上。但是,如果您只是将PCL的字节发送到打印机,则不确定它是否也有效。对于每个DLL导入,我们使用以下方法:
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] RawPrinter di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
我很抱歉这么晚才回答这个问题,但我有一些代码可以完成这项工作。原来不是我写的。我从另一个程序员的帮助站点收到了代码,但我不记得是哪一个。它工作得很好。下面是创建dll的项目。要自己完成,请选择“项目类型”下的“创建:/Project/Class Library选择Visual C”
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace PrintRaw
{
public class RawFilePrint
{
// Structure and API declarions:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DOCINFOA
{
[MarshalAs(UnmanagedType.LPStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)]
public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
// SendBytesToPrinter()
// When the function is given a printer name and an unmanaged array
// of bytes, the function sends those bytes to the print queue.
// Returns true on success, false on failure.
public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
{
Int32 dwError = 0, dwWritten = 0;
IntPtr hPrinter = new IntPtr(0);
DOCINFOA di = new DOCINFOA();
bool bSuccess = false; // Assume failure unless you specifically succeed.
di.pDocName = "RAW Document";
di.pDataType = "RAW";
if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
{
if (StartDocPrinter(hPrinter, 1, di))
{
if (StartPagePrinter(hPrinter))
{
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
if (!bSuccess)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess;
}
public static bool SendFileToPrinter(string szPrinterName, string szFileName)
{
FileStream fs = new FileStream(szFileName, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = new Byte[fs.Length];
bool bSuccess = false;
IntPtr pUnmanagedBytes = new IntPtr(0);
int nLength;
nLength = Convert.ToInt32(fs.Length);
bytes = br.ReadBytes(nLength);
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;
}
public static bool SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes;
Int32 dwCount;
dwCount = szString.Length;
// Assume that the printer is expecting ANSI text, and then convert
// the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
SendBytesToPrinter(szPrinterName, pBytes, dwCount);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
}
}
现在,要使用此代码,请将生成的dll添加为对项目的引用,然后根据需要调用函数。以下是我今天使用的一些代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace PclFontTest
{
class Program
{
static void Main(string[] args)
{
string szPrinterName = @"\\printserver\LaserJet 2420";
StreamReader sr = new StreamReader(@"C:\Fonts\US20HP.FNT");
string line = (char)27 + "*c32545D";
line += sr.ReadToEnd();
line += (char)27 + "*c5F";
PrintRaw.RawFilePrint.SendStringToPrinter(szPrinterName, line);
}
}
}
此程序从文件中读取PCL字体。它用代码包装字体,为其分配32545的字体id,然后调用dll函数SendStringToPrinter。DocumentName是打印作业的显示名称。与磁盘上的文件名没有关系。哈哈,+1对于有趣的例子,我必须在工作中试用。我试图将完整的pcl文档发送到设置为打印到文件的laserjet 4驱动程序,文件上的状态只是显示错误-打印我相信问题在于您正在尝试打印到文件。上面的代码需要一个仅包含PCL代码的文件,并且您希望在不受windows干扰的情况下将其直接发送到打印机。换句话说,您似乎试图打印到一个已经打印到文件中的文件。很棒的代码@James Carr。我想问你一个问题。发送文件时,是否仍要格式化?e、 行距、页边距、分页符等