iangilham.com

By on

software

I stumbled across a fun little way to put arbirary text on the display screen of HP network printers today. The original code is in C# from the days of .NET 1.0–1.1, so I decided to bring it up to date to the current framework. The program uses HP’s Printer Job Language to communicate with the printer. This will probably work with some other printers as well as most manufacturers have some support for PJL, according to Wikipedia.

Why would I want to mess with the printer’s display? For fun. If a printer that ‘feels fat today’ can put a smile on someone’s face then it has all been worthwhile.

// hptalk.cs
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace hptalk
{
    /// make HP network printers talk
    /// code taken from odetocode.com and updated to C# 4.0
    /// ref: http://odetocode.com/humor/68.aspx
    class HpTalk
    {
        static int Main(string[] args)
        {
            if (!ParseArgs(args))
            {
                return -1;
            }
            Console.WriteLine("Host: {0}, Message: {1}", args[0], message);
            try
            {
                var ipEndPoint = new IPEndPoint(
                    Dns.GetHostEntry(args[0]).AddressList[0],
                    PJL_PORT);
                Console.WriteLine("Host IP is {0}", ipEndPoint.ToString());
                using (var socket = new Socket(
                    AddressFamily.InterNetwork,
                    SocketType.Stream,
                    ProtocolType.Tcp))
                {
                    socket.Connect(ipEndPoint);
                    var sendString = String.Format(
                        "\x1B%-12345X@PJL RDYMSG DISPLAY = \"{0}\"\r\n\x1B%-12345X\r\n",
                        message);
                    var sendData = Encoding.ASCII.GetBytes(sendString);
                    var result = socket.Send(sendData, sendData.Length, 0);
                    if (result == 0)
                    {
                        Console.Error.WriteLine("hptalk: socjket error");
                    }
                }
            }
            catch (SocketException ex)
            {
                Console.Error.WriteLine(ex);
                return -1;
            }
            return 0;
        }

        protected static bool ParseArgs(string[] args)
        {
            if (args.Length == 2)
            {
                if (args[1].Length > 16)
                {
                    Console.Error.WriteLine(
                        "hptalk: message must be <= 16 characters");
                    return false;
                }
                else
                {
                    message = args[1];
                }
            }
            else if (args.Length == 1)
            {
                message = GetRandomMessage();
            }
            else
            {
                Console.Error.WriteLine("usage: hptalk printername [message]");
                return false;
            }
            return true;
        }


        public static string GetRandomMessage()
        {
            string[] Messages = {
                            "TOUCH ME",
                            "STEP AWAY",
                            "PAT EATS MICE",
                            "FEED ME",
                            "BE GENTLE",
                            "INSERT COIN",
                            "I FEEL FAT" // etc...
     };

            return Messages[random.Next() % Messages.Length];
        }

        private static Random random = new Random();

        protected const int PJL_PORT = 9100;
        protected static string message = GetRandomMessage();
    }
}

The comparison shows off a few of the changes to the language over the years. C# has obviously come a long way. Most of it is irrelevant to the tiny toy program, but even here, the line count has gone down, a using statement takes care of resource cleanup and the var keyword avoids excessive typing.