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

  [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 发送文件到打印机的更多相关文章

  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. 【代码备份】NLM插值

    文件路径: main.m: %% 测试函数 clc,clear all,close all; %输入的原始小图 ima_ori=double(imread('F:\Users\****n\Docume ...

  2. PHP项目中经常用到的无限极分类函数

    //无限极分类函数调用 function getTree($data,$parent_id = 0,$dept_level = 0){ static $tree = []; foreach ($dat ...

  3. ios 开发之 -- UILabel的text竖行显示

    让UILabel的内容竖行显示,我经常用一下两种方式: 第一种:使用换行符 \n label.text = @"请\n竖\n直\n方\n向\n排\n列"; label.number ...

  4. Qt计算两个时间差

    QTime startTime = QTime::currentTime(); QThread::msleep(SLEEP_TIME_MILL); QTime stopTime = QTime::cu ...

  5. Mybatis框架中Mapper文件传值参数获取。【Mybatis】

    1.参数个数为1个(string或者int) dao层方法为以下两种: /** * 单个int型 */ public List<UserComment> findByDepartmentI ...

  6. [LintCode] 第一个错误的代码版本

    /** * class VersionControl { * public: * static bool isBadVersion(int k); * } * you can use VersionC ...

  7. centos7 安装kafka Manager

    1.安装sbt编译环境 curl https://bintray.com/sbt/rpm/rpm |tee /etc/yum.repos.d/bintray-sbt-rpm.repo yum inst ...

  8. 160418、ztree权限菜单

    1.页面中引用ztree的css和js(大家自行下载ztree) <link rel="stylesheet" href="${ctx}/resources/js/ ...

  9. Yii2 Model的一些常用rules规则,使用Validator验证

    1. Yii2里 model在使用load方法加载浏览器的值的时候,会进行rules验证.这时候可以使用场景,让model对不同场景使用不同验证方式 2. 可以用attributeLabels()来指 ...

  10. Python全栈day28(类的装饰器)

    类是一个对象也可以像函数一样加装饰器 类的装饰器.py def deco(obj): print('======',obj) obj.x=1 obj.y=2 obj.z=3 return obj # ...