This example demonstrates how to send source to GhostScript on the stdin stream, and capture the result on the stdout stream.

Test Program

In this basic test example we start with a simple “Hello World” PostScript document, call the PostscriptToPdf function, and get the resulting PDF document in a string (which we save to check the result is what we expected).

using System;
using System.Diagnostics;
using System.IO;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        string postscript = @"%!PS
/Courier
20 selectfont
72 500 moveto
(Hello world!) show
showpage";

        string pdfText = PostscriptToPdf(postscript);

        using (var fs = new FileStream(@"C:\temp\test.pdf",
            FileMode.Create,
            FileAccess.ReadWrite))
        using (var writer = new BinaryWriter(fs, Encoding.Default))
        {
            writer.Write(pdfText);
        }
    }
}

PostscriptToPdf Function

This function is an automation wrapper around GhostScript. After starting the process we write the PostScript file to the stdin stream (making sure to flush and close the stream when we’re done). Then we read the stderr stream and throw an error if we’ve encountered a problem. Finally, we return contents of the stdout stream.

The key to getting things working is by using ANSI encoding (Encoding.Default) throughout, and understanding the GhostScript parameters.

public static string PostscriptToPdf(string postscript)
{
    Console.OutputEncoding = Encoding.Default;

    var psInfo = new ProcessStartInfo()
    {
        FileName = @"C:\Program Files\gs\gs9.00\bin\gswin32c.exe",
        Arguments = @"-dQUIET -sDEVICE=pdfwrite -o - -_",
        WindowStyle = ProcessWindowStyle.Hidden,
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        StandardOutputEncoding = Encoding.Default,
    };

    var process = Process.Start(psInfo);

    StreamWriter sw = process.StandardInput;
    sw.Write(postscript);
    sw.Flush();
    sw.Close();

    string stderr = process.StandardError.ReadToEnd();

    if (stderr != string.Empty)
        throw new System.InvalidOperationException(stderr);

    return process.StandardOutput.ReadToEnd();
}