1. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    2. public class DOCINFOA
    3. {
    4. [MarshalAs(UnmanagedType.LPStr)]
    5. public string pDocName;
    6. [MarshalAs(UnmanagedType.LPStr)]
    7. public string pOutputFile;
    8. [MarshalAs(UnmanagedType.LPStr)]
    9. public string pDataType;
    10. }
    11. public class PrintCode
    12. {
    13. [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    14. public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
    15. [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    16. public static extern bool ClosePrinter(IntPtr hPrinter);
    17. [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    18. public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
    19. [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    20. public static extern bool EndDocPrinter(IntPtr hPrinter);
    21. [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    22. public static extern bool StartPagePrinter(IntPtr hPrinter);
    23. [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    24. public static extern bool EndPagePrinter(IntPtr hPrinter);
    25. [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    26. public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
    27. /// <summary>
    28. /// 该方法把非托管内存中的字节数组发送到打印机的打印队列
    29. /// </summary>
    30. /// <param name="szPrinterName">打印机名称</param>
    31. /// <param name="pBytes">非托管内存指针</param>
    32. /// <param name="dwCount">字节数</param>
    33. /// <returns>成功返回true,失败时为false</returns>
    34. public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
    35. {
    36. Int32 dwError = 0, dwWritten = 0;
    37. IntPtr hPrinter = new IntPtr(0);
    38. DOCINFOA di = new DOCINFOA();
    39. bool bSuccess = false;
    40. di.pDocName = "My C#.NET RAW Document";
    41. di.pDataType = "RAW";
    42. try
    43. {
    44. // 打开打印机
    45. if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
    46. {
    47. // 启动文档打印
    48. if (StartDocPrinter(hPrinter, 1, di))
    49. {
    50. // 开始打印
    51. if (StartPagePrinter(hPrinter))
    52. {
    53. // 向打印机输出字节
    54. bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
    55. EndPagePrinter(hPrinter);
    56. }
    57. EndDocPrinter(hPrinter);
    58. }
    59. ClosePrinter(hPrinter);
    60. }
    61. if (bSuccess == false)
    62. {
    63. dwError = Marshal.GetLastWin32Error();
    64. }
    65. }
    66. catch (Win32Exception ex)
    67. {
    68. WriteLog(ex.Message);
    69. bSuccess = false;
    70. }
    71. return bSuccess;
    72. }
    73. /// <summary>
    74. /// 发送文件到打印机方法
    75. /// </summary>
    76. /// <param name="szPrinterName">打印机名称</param>
    77. /// <param name="szFileName">打印文件的路径</param>
    78. /// <returns></returns>
    79. public static bool SendFileToPrinter(string szPrinterName, string szFileName)
    80. {
    81. bool bSuccess = false;
    82. try
    83. {
    84. // 打开文件
    85. FileStream fs = new FileStream(szFileName, FileMode.Open);
    86. // 将文件内容读作二进制
    87. BinaryReader br = new BinaryReader(fs);
    88. // 定义字节数组
    89. Byte[] bytes = new Byte[fs.Length];
    90. // 非托管指针
    91. IntPtr pUnmanagedBytes = new IntPtr(0);
    92. int nLength;
    93. nLength = Convert.ToInt32(fs.Length);
    94. // 读取文件内容到字节数组
    95. bytes = br.ReadBytes(nLength);
    96. // 为这些字节分配一些非托管内存
    97. pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
    98. // 将托管字节数组复制到非托管内存指针
    99. Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
    100. // 将非托管字节发送到打印机
    101. bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
    102. // 释放先前分配的非托管内存
    103. Marshal.FreeCoTaskMem(pUnmanagedBytes);
    104. fs.Close();
    105. fs.Dispose();
    106. }
    107. catch (Win32Exception ex)
    108. {
    109. WriteLog(ex.Message);
    110. bSuccess = false;
    111. }
    112. return bSuccess;
    113. }
    114. /// <summary>
    115. /// 将字符串发送到打印机方法
    116. /// </summary>
    117. /// <param name="szPrinterName">打印机名称</param>
    118. /// <param name="szString">打印的字符串</param>
    119. /// <returns></returns>
    120. public static bool SendStringToPrinter(string szPrinterName, string szString)
    121. {
    122. bool flag = false;
    123. try
    124. {
    125. IntPtr pBytes;
    126. Int32 dwCount;
    127. // 获取字符串长度
    128. dwCount = szString.Length;
    129. // 将字符串复制到非托管 COM 任务分配的内存非托管内存块,并转换为 ANSI 文本
    130. pBytes = Marshal.StringToCoTaskMemAnsi(szString);
    131. // 将已转换的 ANSI 字符串发送到打印机
    132. flag = SendBytesToPrinter(szPrinterName, pBytes, dwCount);
    133. // 释放先前分配的非托管内存
    134. Marshal.FreeCoTaskMem(pBytes);
    135. }
    136. catch (Win32Exception ex)
    137. {
    138. WriteLog(ex.Message);
    139. flag = false;
    140. }
    141. return flag;
    142. }
    143. /// <summary>
    144. /// 写入日志方法
    145. /// </summary>
    146. /// <param name="msg">记录信息</param>
    147. public static void WriteLog(string msg)
    148. {
    149. string str = string.Empty;
    150. string path = AppDomain.CurrentDomain.BaseDirectory + "log\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
    151. FileStream filestream = new FileStream(path, FileMode.OpenOrCreate);
    152. str += "************" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "************\r\n";
    153. str += msg;
    154. str += "************" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "************\r\n";
    155. FileStream fs = new FileStream(path, FileMode.Append);
    156. StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);
    157. sw.WriteLine(str);
    158. sw.Flush();
    159. sw.Close();
    160. sw.Dispose();
    161. fs.Close();
    162. fs.Dispose();
    163. }
    164. }

    以上就是全部代码了,调用就很简单了,方法如下:

    1. private void Print_Click(object sender, EventArgs e)
    2. {
    3. //打印文件的路径,该方法获取到的文件路径在应用程序 bin\Debug\ 目录下,所以 ../../ 向上两级目录
    4. string fileName = AppDomain.CurrentDomain.BaseDirectory + @"../../File/demo.txt";
    5. if (PrintCode.SendFileToPrinter("PrinterName", fileName))
    6. {
    7. MessageBox.Show("文件已成功发送至打印队列!","提示信息");
    8. }
    9. }