【发布时间】:2014-11-21 16:36:13
【问题描述】:
我想使用 C# .Net 打印多个静默文件(txt、pdf、htm、...)。我尝试了各种方法,我使用了 ShellExecute、Process、PrintDocument,都没有成功。有一个应用程序“http://www.print-conductor.com/download/”正是我需要的,有人知道它是如何工作的吗?例如,它在不打开 adobe 阅读器的情况下打印 pdf 文件,甚至在任务管理器 adobe 中也没有出现,唯一的要求是让他的应用程序与文件相关联。感谢您的帮助。
使用下面的ShellExecute方法我可以发送打印,但是如果pdf Adobe Reader是打开的,安静的是他没有打开,文件要直接发送到打印队列。
[DllImport("shell32.dll", EntryPoint = "ShellExecute")]
private static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters,
string lpDirectory, ShowCommands nShowCmd);
public bool Print(string fullPath)
{
var result = false;
try
{
var resultPrint = ShellExecute(IntPtr.Zero, "Print", fullPath, "", "", ShowCommands.SwShowminimized).ToInt32();
if (resultPrint > 32) result = true;
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
return result;
}
对于提出问题第一部分的方式,我深表歉意,我为未能交付项目而感到难过,我已经 3 周了,一无所获,请原谅我。
又一次尝试不成功,文件出现在打印队列中,但打印的是空白:
public class RawPrinterHelper
{
// Structure and API declarions:
[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;
}
[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);
// SendBytesToPrinter()
// When the function is given a printer name and an unmanaged array
// of bytes, the function sends those bytes to the print queue.
// Returns true on success, false on failure.
public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
{
Int32 dwError = 0, dwWritten = 0;
IntPtr hPrinter = new IntPtr(0);
DOCINFOA di = new DOCINFOA();
bool bSuccess = false; // Assume failure unless you specifically succeed.
di.pDocName = "My C#.NET RAW Document";
di.pDataType = "RAW";
// Open the printer.
if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
{
// Start a document.
if (StartDocPrinter(hPrinter, 1, di))
{
// Start a page.
if (StartPagePrinter(hPrinter))
{
// Write your bytes.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
// If you did not succeed, GetLastError may give more information
// about why not.
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess;
}
public static bool SendFileToPrinter(string szPrinterName, string szFileName)
{
// Open the file.
FileStream fs = new FileStream(szFileName, FileMode.Open);
// Create a BinaryReader on the file.
BinaryReader br = new BinaryReader(fs);
// Dim an array of bytes big enough to hold the file's contents.
Byte[] bytes = new Byte[fs.Length];
bool bSuccess = false;
// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr(0);
int nLength;
nLength = Convert.ToInt32(fs.Length);
// Read the contents of the file into the array.
bytes = br.ReadBytes(nLength);
// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;
}
public static bool SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes;
Int32 dwCount;
// How many characters are in the string?
dwCount = szString.Length;
// Assume that the printer is expecting ANSI text, and then convert
// the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
// Send the converted ANSI string to the printer.
SendBytesToPrinter(szPrinterName, pBytes, dwCount);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
}
class Program
{
private static void Main(string[] args)
{
var defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();
RawPrinterHelper.SendFileToPrinter(defaultPrintQueue.FullName, @"C:\Temp\Teste.pdf");
}
}
使用下面的选项,Adobe Reader 也会打开并保持打开状态:
public void Print(string fullPath, string printerName)
{
Process process = new Process
{
StartInfo =
{
FileName = fullPath,
UseShellExecute = true,
Verb = "printto",
Arguments = "\"" + printerName + "\""
}
};
process.Start();
}
- Visual Studio 2013、C#、Windows 8.1
【问题讨论】:
-
你说你尝试了各种方法,但你没有解释它们是如何不起作用的。我们怎么知道你做错了什么? “无声打印”是什么意思?
-
在 Stack Overflow 上通常不会很好地接受仅是需求而无需付出任何努力的问题。相反,显示(在代码中)已尝试解决问题的方法以及当前遇到的问题以及具体的、可回答的、客观的问题。
-
是的,展示你的代码,只有我们才能理解你使用了什么逻辑以及失败的地方
-
再次为我提出问题的方式道歉,我有点失望没有得到适合我的形状,我编辑了问题并输入了我使用的代码。谢谢!