C# 使用 Windows API 发送文件到打印机
最近需要做一个打印的功能,于是在网上找到了这么一个方法。
- [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;
- }
- public class PrintCode
- {
- [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);
- /// <summary>
- /// 该方法把非托管内存中的字节数组发送到打印机的打印队列
- /// </summary>
- /// <param name="szPrinterName">打印机名称</param>
- /// <param name="pBytes">非托管内存指针</param>
- /// <param name="dwCount">字节数</param>
- /// <returns>成功返回true,失败时为false</returns>
- public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
- {
- Int32 dwError = , dwWritten = ;
- IntPtr hPrinter = new IntPtr();
- DOCINFOA di = new DOCINFOA();
- bool bSuccess = false;
- di.pDocName = "My C#.NET RAW Document";
- di.pDataType = "RAW";
- try
- {
- // 打开打印机
- if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
- {
- // 启动文档打印
- if (StartDocPrinter(hPrinter, , di))
- {
- // 开始打印
- if (StartPagePrinter(hPrinter))
- {
- // 向打印机输出字节
- bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
- EndPagePrinter(hPrinter);
- }
- EndDocPrinter(hPrinter);
- }
- ClosePrinter(hPrinter);
- }
- if (bSuccess == false)
- {
- dwError = Marshal.GetLastWin32Error();
- }
- }
- catch (Win32Exception ex)
- {
- WriteLog(ex.Message);
- bSuccess = false;
- }
- return bSuccess;
- }
- /// <summary>
- /// 发送文件到打印机方法
- /// </summary>
- /// <param name="szPrinterName">打印机名称</param>
- /// <param name="szFileName">打印文件的路径</param>
- /// <returns></returns>
- public static bool SendFileToPrinter(string szPrinterName, string szFileName)
- {
- bool bSuccess = false;
- try
- {
- // 打开文件
- FileStream fs = new FileStream(szFileName, FileMode.Open);
- // 将文件内容读作二进制
- BinaryReader br = new BinaryReader(fs);
- // 定义字节数组
- Byte[] bytes = new Byte[fs.Length];
- // 非托管指针
- IntPtr pUnmanagedBytes = new IntPtr();
- int nLength;
- nLength = Convert.ToInt32(fs.Length);
- // 读取文件内容到字节数组
- bytes = br.ReadBytes(nLength);
- // 为这些字节分配一些非托管内存
- pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
- // 将托管字节数组复制到非托管内存指针
- Marshal.Copy(bytes, , pUnmanagedBytes, nLength);
- // 将非托管字节发送到打印机
- bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
- // 释放先前分配的非托管内存
- Marshal.FreeCoTaskMem(pUnmanagedBytes);
- fs.Close();
- fs.Dispose();
- }
- catch (Win32Exception ex)
- {
- WriteLog(ex.Message);
- bSuccess = false;
- }
- return bSuccess;
- }
- /// <summary>
- /// 将字符串发送到打印机方法
- /// </summary>
- /// <param name="szPrinterName">打印机名称</param>
- /// <param name="szString">打印的字符串</param>
- /// <returns></returns>
- public static bool SendStringToPrinter(string szPrinterName, string szString)
- {
- bool flag = false;
- try
- {
- IntPtr pBytes;
- Int32 dwCount;
- // 获取字符串长度
- dwCount = szString.Length;
- // 将字符串复制到非托管 COM 任务分配的内存非托管内存块,并转换为 ANSI 文本
- pBytes = Marshal.StringToCoTaskMemAnsi(szString);
- // 将已转换的 ANSI 字符串发送到打印机
- flag = SendBytesToPrinter(szPrinterName, pBytes, dwCount);
- // 释放先前分配的非托管内存
- Marshal.FreeCoTaskMem(pBytes);
- }
- catch (Win32Exception ex)
- {
- WriteLog(ex.Message);
- flag = false;
- }
- return flag;
- }
- /// <summary>
- /// 写入日志方法
- /// </summary>
- /// <param name="msg">记录信息</param>
- public static void WriteLog(string msg)
- {
- string str = string.Empty;
- string path = AppDomain.CurrentDomain.BaseDirectory + "log\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
- FileStream filestream = new FileStream(path, FileMode.OpenOrCreate);
- str += "************" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "************\r\n";
- str += msg;
- str += "************" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "************\r\n";
- FileStream fs = new FileStream(path, FileMode.Append);
- StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);
- sw.WriteLine(str);
- sw.Flush();
- sw.Close();
- sw.Dispose();
- fs.Close();
- fs.Dispose();
- }
- }
以上就是全部代码了,调用就很简单了,方法如下:
- private void Print_Click(object sender, EventArgs e)
- {
- //打印文件的路径,该方法获取到的文件路径在应用程序 bin\Debug\ 目录下,所以 ../../ 向上两级目录
- string fileName = AppDomain.CurrentDomain.BaseDirectory + @"../../File/demo.txt";
- if (PrintCode.SendFileToPrinter("PrinterName", fileName))
- {
- MessageBox.Show("文件已成功发送至打印队列!","提示信息");
- }
- }
C# 使用 Windows API 发送文件到打印机的更多相关文章
- ansible管理windows (发送文件)
https://github.com/ansible/ansible/raw/devel/examples/scripts/ConfigureRemotingForAnsible.ps1 环境: 服务 ...
- 使用Windows API发送HTTP请求
先看一个简单的GET示例 #include <Windows.h> #include <winhttp.h> #include <stdio.h> int main ...
- MT4调用Windows API进行文件读写操作
/*导入相关函数*/ #import "kernel32.dll" int CreateDirectoryW(string directoryName,int type); int ...
- 【转】用C#调用Windows API向指定窗口发送
一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式 ...
- 用C#调用Windows API向指定窗口发送按键消息 z
用C#调用Windows API向指定窗口发送 一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.Interop ...
- 用C#调用Windows API向指定窗口发送按键消息
一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式 ...
- 用Windows API函数(CreateFile/ReadFile/WriteFile/CloseHandle)完成文件拷贝程序(初级版)
文件拷贝程序 程序类型:Console 参数:源文件名 目的文件名 要求:1.只能使用Windows API函数(CreateFile/ReadFile/WriteFile/CloseHandle ...
- LoadLibrary文件路径及windows API相关的文件路径问题
LoadLibrary HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName ); Loads the specified module into ...
- 学习:Windows API核心DLL文件
在 Windows 的系统目录中,存在着很多的动态链接库文件(DLL 文件).这些 DLL 文件中包括了 Windows API 函数可执行程序. DLL 将各函数"导出",这样应 ...
随机推荐
- Linux Shell Vim 经常使用命令、使用技巧总结
前言 本文总结了自己实际开发中的经常使用命令,不定时更新,方便自己和其它人查阅. 如有其它提高效率的使用技巧.欢迎留言. 本文地址 http://blog.csdn.net/never_cxb/art ...
- C# 将MSMQ消息转换成Json格式
PS:主要就是一个配置文件和一个转换函数 配置文件app.config 之前要ADD reference --> system.configuration & using.syst ...
- FormData异步上传
1.代码片段一: ajaxUpload: function () { var url = this.$avatarForm.attr('action'), data = new FormData(th ...
- MySQL--执行mysql脚本及其脚本编写
http://www.cnblogs.com/kex1n/archive/2010/03/26/2286504.html
- WebGL中的OpenGL着色器语言
在webgl中,调用了OpenGL-ES-2.0的API,而在OpenGL-ES专为嵌入式设备设计,其和其它设备一样,都是使用GLSL(GL Shading Language)来编写片段程序并执行于G ...
- Hibernate_day03--Hibernate多对多操作
Hibernate多对多操作 多对多映射配置 以用户和角色为例演示 第一步 创建实体类,用户和角色 第二步 让两个实体类之间互相表示 (1)一个用户里面表示所有角色,使用set集合 具体: User. ...
- onTouch事件分发
事件机制 我们知道view中有onTouch,onClick, 1.并且onTouch优先于onClick执行, 2.onTouch有返回值,为true时onClick并不再执行了 因为一切VIew都 ...
- measure layout onMeasure() onLayout()
1.onMeasure() 在这个函数中,ViewGroup会接受childView的请求的大小,然后通过childView的 measure(newWidthMeasureSpec, heightM ...
- js小功能实现
发送随机数手机验证码60秒倒计时 mm.mobileCheck = function(t){ var mobile = $("#user_mobile").val(); if(&q ...
- 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, ...