最近需要做一个打印的功能,于是在网上找到了这么一个方法。

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

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

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

C# 使用 Windows API 发送文件到打印机的更多相关文章

  1. ansible管理windows (发送文件)

    https://github.com/ansible/ansible/raw/devel/examples/scripts/ConfigureRemotingForAnsible.ps1 环境: 服务 ...

  2. 使用Windows API发送HTTP请求

    先看一个简单的GET示例 #include <Windows.h> #include <winhttp.h> #include <stdio.h> int main ...

  3. MT4调用Windows API进行文件读写操作

    /*导入相关函数*/ #import "kernel32.dll" int CreateDirectoryW(string directoryName,int type); int ...

  4. 【转】用C#调用Windows API向指定窗口发送

    一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式 ...

  5. 用C#调用Windows API向指定窗口发送按键消息 z

    用C#调用Windows API向指定窗口发送 一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.Interop ...

  6. 用C#调用Windows API向指定窗口发送按键消息

    一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式 ...

  7. 用Windows API函数(CreateFile/ReadFile/WriteFile/CloseHandle)完成文件拷贝程序(初级版)

    文件拷贝程序 程序类型:Console 参数:源文件名   目的文件名 要求:1.只能使用Windows API函数(CreateFile/ReadFile/WriteFile/CloseHandle ...

  8. LoadLibrary文件路径及windows API相关的文件路径问题

    LoadLibrary HMODULE WINAPI LoadLibrary( _In_  LPCTSTR lpFileName ); Loads the specified module into ...

  9. 学习:Windows API核心DLL文件

    在 Windows 的系统目录中,存在着很多的动态链接库文件(DLL 文件).这些 DLL 文件中包括了 Windows API 函数可执行程序. DLL 将各函数"导出",这样应 ...

随机推荐

  1. Linux Shell Vim 经常使用命令、使用技巧总结

    前言 本文总结了自己实际开发中的经常使用命令,不定时更新,方便自己和其它人查阅. 如有其它提高效率的使用技巧.欢迎留言. 本文地址 http://blog.csdn.net/never_cxb/art ...

  2. C# 将MSMQ消息转换成Json格式

    PS:主要就是一个配置文件和一个转换函数 配置文件app.config  之前要ADD reference -->   system.configuration & using.syst ...

  3. FormData异步上传

    1.代码片段一: ajaxUpload: function () { var url = this.$avatarForm.attr('action'), data = new FormData(th ...

  4. MySQL--执行mysql脚本及其脚本编写

    http://www.cnblogs.com/kex1n/archive/2010/03/26/2286504.html

  5. WebGL中的OpenGL着色器语言

    在webgl中,调用了OpenGL-ES-2.0的API,而在OpenGL-ES专为嵌入式设备设计,其和其它设备一样,都是使用GLSL(GL Shading Language)来编写片段程序并执行于G ...

  6. Hibernate_day03--Hibernate多对多操作

    Hibernate多对多操作 多对多映射配置 以用户和角色为例演示 第一步 创建实体类,用户和角色 第二步 让两个实体类之间互相表示 (1)一个用户里面表示所有角色,使用set集合 具体: User. ...

  7. onTouch事件分发

    事件机制 我们知道view中有onTouch,onClick, 1.并且onTouch优先于onClick执行, 2.onTouch有返回值,为true时onClick并不再执行了 因为一切VIew都 ...

  8. measure layout onMeasure() onLayout()

    1.onMeasure() 在这个函数中,ViewGroup会接受childView的请求的大小,然后通过childView的 measure(newWidthMeasureSpec, heightM ...

  9. js小功能实现

    发送随机数手机验证码60秒倒计时 mm.mobileCheck = function(t){ var mobile = $("#user_mobile").val(); if(&q ...

  10. nginx分发请求的2种方式:1、指明server_name;2、通过location过滤uri来分发请求;

    user nginx; worker_processes 8; # = cpu num; error_log /data/nginx/log/error/error.log warn; # warn, ...