RedMon

Redirection Port Monitor (RedMon) is a virtual printer port that can redirect output to a file or program which can in turn process the printer data or send it to a physical printer.

Installation
Add Redirected Port (RPT1:)
Configure Redirected Port (RPT1:)

Select a printer, then go to the “Printer Properties” (right-click printer). Assign the RPT: port for that printer, then click on the button “Configure Port”.

Set the RPT1: port properties

Example Translator

RedMon passes the original print job via STDIN to the program C:\Apps\PrnTranslator.exe. It also passes a command line argument specifying where PrinterTranslator should save the output print job after making its changes. RedMon then takes the file and spools it directly to the selected printer, in this case “Xerox Phaser”.

PrinterTranslator is a basic program which accepts the STDIN input from RedMon, makes a few changes to the formatting and outputs the file. You can see the source code below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
 
namespace PrinterTranslator
{
  class Program
  {
	  static void Main(string[] args)
	  {
		  // Check if an output filename was provided and close if it wasn't.
		  string Filename = "";
		  if (args.Length == 0)
		  {
			  Console.WriteLine("No file was specified to write the translated data to... closing.");
			  return;
		  }
		  else
		  {
			  Filename = args[0];
		  }
 
		  bool UsingSTDIN = false;
		  string InputFile = "";
		  try
		  {
			  // This function throws an InvalidOperationException when the input is coming from STDIN.
			  UsingSTDIN = System.Console.KeyAvailable;
 
			  if (!UsingSTDIN)
				  return;
		  }
		  catch (InvalidOperationException e)
		  {
			  // Since we got this exception we know we got data from STDIN.
			  InputFile = System.Console.In.ReadToEnd();
		  }
 
		  string[] LinesToProcess = InputFile.Split('\f');
 
		  // Prep the file so we can save the fixed lines as we run through them.
		  StreamWriter OutFile = new StreamWriter(Filename);
 
		  // Fix the file formatting.
		  foreach (string Line in LinesToProcess)
		  {
			  string newLine = Line;
 
			  // Make sure all quotes are ended.
			  if (Line.Contains('"'))
			  {
				  int FirstQuote = Line.IndexOf('"');
 
				  if (FirstQuote != -1)
				  {
					  int LastQuote = Line.LastIndexOf('"');
 
					  if (FirstQuote == LastQuote)
						  newLine += '"';
				  }
			  }
 
			  // Write out the fixed line.
			  // Check if the string already contains a carriage return. 
                          // In that case, we do not want to do a WriteLine as 
                          // we will actually write 2 lines.
			  if (!(newLine == "\r\n"))
			  {
				  OutFile.WriteLine(newLine);
			  }
		  }
		  OutFile.Close();
	  }
  }
}
Example Uploader
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Web;
 
namespace PrinterUploader
{
    class Program
    {
        const string LABEL_LOG_URL = "http://audina.net/support/print-log/web/api-raw/create";
 
        static void Main(string[] args)
        {
            bool CreateInputCopy = false;
            string InputFilename = string.Empty;
            string InputFileContent = string.Empty;
            string InputCopyFilename = string.Empty;
 
            #region Process command line parameters
 
            // Check if an output filename was provided and close if it wasn't.
            if (args.Length > 0)
            {
                foreach (string Argument in args)
                {
                    if (Argument.StartsWith("/input="))
                    {
                        InputFilename = Argument.Substring(Argument.IndexOf('=') + 1);
                    }
                    else if (Argument.StartsWith("/copyinput="))
                    {
                        CreateInputCopy = true;
                        InputCopyFilename = Argument.Substring(Argument.IndexOf('=') + 1);
                    }
                }
            }
 
            #endregion
 
            #region Get input from file/stdin
 
            // Try using standard in if an input filename isn't passed in
            if (InputFilename == string.Empty)
            {
                try
                {
                    // This function throws an InvalidOperationException when the input is coming from STDIN.
                    Console.WriteLine("Checking for standard in input.");
                    bool test = System.Console.KeyAvailable;
                    Console.WriteLine("Standard in input not available.");
 
                    if (args.Length == 0)
                    {
                        Console.WriteLine("Closing due to no input.");
                        return;
                    }
                }
                catch (InvalidOperationException)
                {
                    // Since we got this exception we know we got data from STDIN.
                    Console.WriteLine("Using standard in input.");
                    InputFileContent = System.Console.In.ReadToEnd();
                    Console.WriteLine(InputFileContent);
                }
            }
            else
            {
                try
                {
                    Console.WriteLine("Getting input from filename, {0}", InputFilename);
 
                    using (TextReader tr = File.OpenText(InputFilename))
                    {
                        InputFileContent = tr.ReadToEnd();
                    }
                }
                catch (Exception e)
                {
                    if (e is FileNotFoundException || e is DirectoryNotFoundException)
                    {
                        Console.WriteLine("Input file was not found.");
                        System.Threading.Thread.Sleep(5 * 1000);
                    }
 
                    return;
                }
            }
 
            if (InputFileContent == string.Empty)
            {
                Console.WriteLine("No input file content was found.");
                System.Threading.Thread.Sleep(5 * 1000);
                return;
            }
 
            #endregion
 
            #region Output copies and handle passthrough
 
            if (CreateInputCopy)
            {
                Console.WriteLine("Creating an input copy, {0}", InputCopyFilename);
 
                try
                {
                    using (StreamWriter CopyFile = new StreamWriter(InputCopyFilename))
                    {
                        CopyFile.Write(InputFileContent);
                        CopyFile.Close();
                    }
                }
                catch
                {
                    Console.WriteLine(string.Format("Copying input to {0} failed.", InputCopyFilename));
                    Console.WriteLine(InputFileContent);
                    System.Threading.Thread.Sleep(5 * 1000);
                }
            }
 
            #endregion
 
            #region Upload the file
 
            // Upload the file
            LogAddressLabel(InputFileContent);
 
            #endregion
        }
 
        public static string LogAddressLabel(string LabelText)
        {
            Dictionary<string, string> postParameters = new Dictionary<string, string>();
 
            if (LabelText == string.Empty)
                LabelText = "empty";
 
            postParameters.Add("category", "Address Label");
            postParameters.Add("data", LabelText);
 
            string result = "";
 
            try
            {
                result = HttpPostRequest(LABEL_LOG_URL, postParameters);
            }
            catch (WebException exc)
            {
                // Only ignore errors with: 404 Not Found.
                if (!exc.Message.Contains("(404) Not Found."))
                {
                    throw exc;
                }
            }
 
            return result;
        }
 
        public static string HttpPostRequest(string url, Dictionary<string, string> postParameters, 
            bool mustAuthenticate=false, string aUsername="", string aPassword="")
        {
            string postData = "";
 
            foreach (string key in postParameters.Keys)
            {
                postData += HttpUtility.UrlEncode(key) + "="
                          + HttpUtility.UrlEncode(postParameters[key]) + "&";
            }
 
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
            webRequest.Method = "POST";
 
            // authentication
            if (mustAuthenticate)
            {
                webRequest.PreAuthenticate = mustAuthenticate;
                webRequest.AuthenticationLevel = AuthenticationLevel.MutualAuthRequested;
 
                var cache = new CredentialCache();
                cache.Add(new System.Uri(url), "Basic", new NetworkCredential(aUsername, aPassword));
                webRequest.Credentials = cache;
                //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(AcceptAllCertifications);
            }
 
            byte[] data = System.Text.Encoding.ASCII.GetBytes(postData);
 
            webRequest.ContentType = "application/x-www-form-urlencoded";
            //webRequest.ContentType = "application/json; charset=utf-8";
            webRequest.ContentLength = data.Length;
 
            Stream requestStream = webRequest.GetRequestStream();
            requestStream.Write(data, 0, data.Length);
            requestStream.Close();
 
            string responseFromServer = "";
            try
            {
                HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
                Stream responseStream = webResponse.GetResponseStream();
 
                StreamReader streamReader = new StreamReader(responseStream, System.Text.Encoding.Default);
                responseFromServer = streamReader.ReadToEnd();
 
                streamReader.Close();
                responseStream.Close();
                webResponse.Close();
            }
            catch (WebException exc)
            {
                // Do not ignore any web exception
                throw exc;
            }
 
            return responseFromServer;
        }
    }
}