Click here to Skip to main content
13,146,742 members (79,819 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

7.4K views
14 bookmarked
Posted 28 Sep 2016

Printing PDF using Ghostscript in C#

, 28 Sep 2016
Rate this:
Please Sign up or sign in to vote.
How to print PDF using Ghostscript in C#

This logic will print PDF documents, using GhostScript, without opening or using Adobe.
You will need to have Ghostscript installed on the local system for this to work

Finding a PDF Application 
This finds the GhostScript exe application path

Create Pool of reg keys
This is the pool of different possibilities of registration keys, which will contain the path to the exe 

<code> private static void createRegistrationKey()
        {

            RegistrationKey = new Liststring, string>>();
            RegistrationKey.Add(new Tuple<string, string>("Ghost", @"SOFTWARE\GPL Ghostscript"));
            RegistrationKey.Add(new Tuple<string, string>("Ghost",@"SOFTWARE\AFPL Ghostscript"));
          }
</code>

Get path from the registration
Using data from the pool it will check the reg for the exe path, The ghostscript does not contain the value in the primary key, it within the sub key.
Once within the sub key, the path returned is the root path or dll. So I have done a small hack to the code which will return the exe file, if this pathway is hit (ONLY because, I know that the exe name is correct)

<code>private static Tuple<string,string> getRegistryApplicationPath(string keyTitle, string applicationKey)
        {
            RegistryKey key = Registry.LocalMachine.OpenSubKey(applicationKey);
            if (key != null)
            {
                if(key.ValueCount > 0)
                {
                    return new Tuple<string, string>(keyTitle, key.GetValue("").ToString());
                }
                else if (key.SubKeyCount > 0)
                {
                    foreach(var item in key.GetSubKeyNames())
                    {
                        var inner = key.OpenSubKey(item);
                        foreach(var valueInner in inner.GetValueNames())
                        {
                            string inner1 = inner.GetValue(valueInner).ToString();
                            if (!inner1.Contains(".exe") && !inner1.Contains(".dll") && inner1.Contains("GPLGS"))
                            {
                              //As the folder exists, I will just add the exe name, which I know it will be and return the full path
                                return new Tuple<string, string>(keyTitle, Path.Combine(inner1, "gswin32c.exe"));

                            }else if (inner1.Contains(".exe") || inner1.Contains(".dll"))
                            {
                                return new Tuple<string, string>(keyTitle, Path.Combine(inner1));
                            }

                        }
                    }
                }
                
            }

            return new Tuple<string,string>(String.Empty,String.Empty);
        }</code>

Get installer exe path
Loop through each item within the queue, to see if there is a reg record

<code>private static void getInstalledApplicationPath()
        {
            
            
            foreach (var s in RegistrationKey)
            {
                allocatedPath = getRegistryApplicationPath(s.Item1, s.Item2);
                if (!String.IsNullOrEmpty(allocatedPath.Item1))
                {
                    break;
                }
            }
        }
</code>

Allocation controller method
This method controls the allocation logic

<code> public static Tuple<string, string> Allocate()
        {

            createRegistrationKey();
            getInstalledApplicationPath();

            return allocatedPath;
        }</code>

Printing the PDF document 
This uses the Allocation logic to find the exe path and then it sends the document to the printer, without any popups
Create the Process start info object
Creates the ProcessStartInfo object, so GhostScript can print the pdf

<code>    private static void setProcess()
        {
          startInfo = new ProcessStartInfo();
            startInfo.Arguments =
                String.Format(
                    " -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -q -dNumCopies=1 -sDEVICE=mswinpr2 -sOutputFile=\"\\\\spool\\{0}\" \"{1}\"",
                    printerName, printFileName);
            startInfo.FileName = applicationPath;
            startInfo.UseShellExecute = false;   

        }</code>

Get the current default printer
This get the printer name for the default printer within windows

<code>private static void getPrinterName()
        {
            PrintDialog pt = new PrintDialog();
            printerName = pt.PrinterSettings.PrinterName;

        }</code>

Run the process
Creates controls the creation of the process to send the PDF to the printer

<code> public static void Print(string path,  string exePath)
        {
            var allocation = PDFLibrary.ApplicationEXEPath.Allocate();
            printFileName = path;
            applicationPath = allocation.Item2;
                  
            getPrinterName();
          
            setTracking();
                       
            
            if (!String.IsNullOrEmpty(applicationPath))
            {
                setProcess();

                using (var process = Process.Start(startInfo))
                {

                    Console.WriteLine("Process started");
                    Console.WriteLine("Process Id: " + process.Id.ToString());
                    Console.WriteLine("Process Machine name: " + process.MachineName.ToString());

                    Console.WriteLine("Wait for Process to exit");
                    process.WaitForExit();                                     

                    Console.WriteLine( "Closing Process");
                    closeProcess(process);                   
                                        
                }
                reJoinThread();

            }
            else
            {
                MessageBox.Show(LanguageHelper.GetString("dlgPDFViewer.CantFindPDFApplication"), "Health Options®", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
        }

private static void closeProcess(Process process)
        {
            try
            {
                process.CloseMainWindow();
                process.Kill();
            }
            catch (Exception e)
            {
                
            }
        }

        private static void reJoinThread()
        {
            try
            {
                Console.WriteLine(""Try and re-join the Tracking thread");
                trackingThread.Join();
               Console.WriteLine(""Thread has ended");
            }
            catch (Exception e)
            {
               
            }

        }</code>

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Thomas Cooper
United Kingdom United Kingdom
No Biography provided

You may also be interested in...

Pro
Pro

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170915.1 | Last Updated 29 Sep 2016
Article Copyright 2016 by Thomas Cooper
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid