前言
总结一些控制打印机的方法以及存在的问题,本文不包括window form的打印机组件使用,只是局限于纯代码层面
1.0 使用Process类
打印文本和图片均可以采用process类调用进程进行,但是在打印图片时会弹出打印预览的框,不容易解决。
如果不想弹窗, 除了设置p.StartInfo.CreateNoWindow = true;外还要p.Close();
private static void PrintPdf(string file)
{
//string file = @"D:\document.pdf";
ProcessStartInfo printProcessInfo = new ProcessStartInfo()
{
Verb = "print",
CreateNoWindow = true,
FileName = file,
WindowStyle = ProcessWindowStyle.Hidden
};
Process printProcess = new Process();
printProcess.StartInfo = printProcessInfo;
printProcess.Start();
printProcess.Dispose();
}
1.1 PrintDocument
打印图片时不会弹框,但是在unity中需要引入相应的dll,相关dll可以去安装目录(C:\Program Files (x86)\Unity\551\Editor\Data\Mono\lib\mono\2.0)中查找,并放到plugins目录下,但是如果之前unity中存在相关dll,直接覆盖重启也存在问题,所以此时直接删除plugin下的dll,重新考入就可以,unity使用dll的特征问题,直接覆盖是没用的,已经加载到内存中了,要么直接删除,重新考入,要么重启unity。但是用printDocument打印pdf时由于文件的读取方式问题(csdn范例为通过streamreader一行一行读取),所以打印乱码,简易采用process类打印,或用其他插件。
printdocument打印图片代码:
static void Main(string[] args)
{
string printFile = args[0];
//string printerName = args[1];
int width;
int height;
if (!int.TryParse(args[1], out width))
{
width = 355;
}
if (!int.TryParse(args[2], out height))
{
height = 500;
}
//Console.WriteLine("Print size:" + width + " " + height);
PrintDocument pd = new PrintDocument();
pd.PrintController = new StandardPrintController();
pd.PrintPage += (o, e) =>
{
Image img = Image.FromFile(printFile);
int imgWidth = (int)(img.Height * 0.7f);
e.Graphics.DrawImage(img, new Rectangle(0, 0, width, height), new Rectangle(0, 0, imgWidth, img.Height), GraphicsUnit.Pixel);//通用
};
try
{
pd.Print();
Console.WriteLine("success");
}
catch (Exception ex)
{
Console.WriteLine("failed:" + ex.Message);
}
//btnPrint_Click();
Console.ReadKey();
}
打印的相关参数可以在电脑设置-打印机-首选项中提前设置好。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PrintPdf
{
class Program
{
private static StreamReader sr;
public static bool Print(string str)
{
bool result = true;
try
{
sr = new StreamReader(str);
PrintDocument pd = new PrintDocument();
pd.PrintController = new System.Drawing.Printing.StandardPrintController();
pd.DefaultPageSettings.Margins.Top = 2;
pd.DefaultPageSettings.Margins.Left = 0;
pd.DefaultPageSettings.PaperSize = new PaperSize("tom", 320, 5150);
pd.PrinterSettings.PrinterName = pd.DefaultPageSettings.PrinterSettings.PrinterName;//默认打印机
pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
try
{
pd.Print();
}
catch (Exception exs)
{
Console.WriteLine("打印出错:" + exs.ToString());
pd.PrintController.OnEndPrint(pd, new PrintEventArgs());
}
}
catch (Exception ex)
{
result = false;
}
finally
{
if (sr != null)
sr.Close();
}
return result;
}
private static void pd_PrintPage(object sender, PrintPageEventArgs ev)
{
Font printFont = new Font("Arial", 9);//打印字体
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = ev.MarginBounds.Left;
float topMargin = ev.MarginBounds.Top;
String line = "";
linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics);
while (count < linesPerPage && ((line = sr.ReadLine()) != null))
{
yPos = topMargin + (count * printFont.GetHeight(ev.Graphics));
ev.Graphics.DrawString(line, printFont, Brushes.Black,
leftMargin, yPos, new StringFormat());
count++;
}
// If more lines exist, print another page.
if (line != null)
ev.HasMorePages = true;
else
ev.HasMorePages = false;
}
static void Main(string[] args)
{
//string file = @"D:\命令.txt";
string file = @"D:\document.pdf";
//Print(file);
ProcessStartInfo printProcessInfo = new ProcessStartInfo()
{
Verb = "print",
CreateNoWindow = true,
FileName = file,
WindowStyle = ProcessWindowStyle.Hidden
};
Process printProcess = new Process();
printProcess.StartInfo = printProcessInfo;
printProcess.Start();
//printProcess.WaitForInputIdle();
//Thread.Sleep(3000);
//if (false == printProcess.CloseMainWindow())
//{
// printProcess.Kill();
//}
Console.ReadKey();
}
}
}
1.2 获取打印机当前打印状态
.net中下述代码可运行,但在unity中则无法执行,如果是在windows下运行,可以把下述代码编译,在unity中调用其exe
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Management;
namespace GetPrinterStatus
{
class Program
{
enum Status
{
OTHERS = 1,
UNKNOWN,
SPARE,
PRINTING,
PREHEAT,
STOP,
ONPRINTING,
OFF
}
private static Status GetPrinterStatus(string PrinterDevice)
{
Status result = 0;
string path = @"win32_printer.DeviceId='" + PrinterDevice + "'";
ManagementObject printer = new ManagementObject(path);
printer.Get();
result = (Status)Convert.ToInt32(printer.Properties["PrinterStatus"].Value);
return result;
}
static int Main(string[] args)
{
return (int)GetPrinterStatus(args[0]);
}
}
}