1

HELP

Our application has been printing PDF documents using the ProcessStart logic for sometime, but now its stopped working.

So I've been given the task of finding an alternative and I thought I had. The below code works with all our network printers, but when I send the PDF document to a local USB printer it does not want to print.

The document is within the Printer queue, for the local printer and saying printing, but the printer does not want to print it. If I sen another document to the same printer, it will print the new document (outside of code, using Notepad) and then the PDF print item disappears.

I've gone around the web and I seem to go round and round, but I can't seem to find an answer which will work with our issue.

Example stack over flow fix, which does not work How to send a raw ZPL to zebra printer using C# via USB

Screen shot of the queue enter image description here

Code I'm currently using

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);

    private static string  documentName = "HO Document";
    // 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 = documentName;
        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;
    }



    private static void trackPrint(string printerName)
    {
        dlgProgressStatus statusBar = new dlgProgressStatus();


        statusBar.SetDefault("Document Printing Tracking ","", 4);
        statusBar.SetStatus("", false);
        statusBar.Show();
        statusBar.Refresh();

        Stopwatch timeTaken = new Stopwatch();
        timeTaken.Start();
        Utilities.DebugSolution.SetMessageUniqueFile("Printing", "Tracking printing");
        while (!Utilities.Printer.JobOnQueue(printerName, documentName, ref statusBar))
        {
            Utilities.DebugSolution.SetMessageUniqueFile("Printing", "Waiting for Job on Queue");
            System.Threading.Thread.Sleep(100);
            if (timeTaken.Elapsed.Minutes > 1)
            {
                MessageBox.Show(LanguageHelper.GetString("dlgPDFViewer.PrintingQueueTimeOut"), "Health Options®", MessageBoxButtons.OK, MessageBoxIcon.Error);
                break;
            }
        }

        statusBar.Close();
        statusBar.Dispose();



    }

    public static bool SendFileToPrinter(string szPrinterName, string szFileName, string printingDocumentName)
    {
        Utilities.DebugSolution.SetMessageUniqueFile("Printing", "Sending to Printer");
        Utilities.DebugSolution.SetMessageUniqueFile("Printing", "File path: " + szFileName);
        Utilities.DebugSolution.SetMessageUniqueFile("Printing", "Exisits: " + File.Exists(szFileName).ToString());
        Utilities.DebugSolution.SetMessageUniqueFile("Printing", "Printer Name: " + szPrinterName);
        if (!String.IsNullOrEmpty(printingDocumentName))
            documentName = printingDocumentName;

        // Open the file.
        using (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);


            trackPrint(szPrinterName);
            //Remove temp file      
            System.GC.Collect();
            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;
    }
Community
  • 1
  • 1
Chris Cooper
  • 389
  • 3
  • 16
  • "which does not work" What does this mean? Exceptions? Unexpected results? – MakePeaceGreatAgain Aug 11 '16 at 11:34
  • No the pdf does not print out. There is no error and the document just sitson the queue, saying printing. Code thinks the job is done. – Chris Cooper Aug 11 '16 at 11:36
  • 1
    Are you trying to print a file simply by copying the file's contents to the printer? That's not how printers work. Your application has to *render* whatever it wants to display in a language that the printer understands. In any case, .NET already has classes for printing. you *don't* need to use Interop – Panagiotis Kanavos Aug 11 '16 at 11:38
  • The code sends the PDF as a raw item and the printer just prints it. The code works with network printers, but if I send the same PDF using same code, but only chaning the printer to a USB printer the printer does not want to print the document – Chris Cooper Aug 11 '16 at 11:45

0 Answers0