Tuesday, June 16, 2015

Installing PhantomJS as a Windows Service (BONUS: Using PhantomJS with ColdFusion)

If you aren't familiar with PhantomJS, you probably wouldn't be looking at the blog post. Regardless, "PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG." available at http://phantomjs.org/.

PhantomJS is a very powerful and versatile tool. Once you get comfortable with PhantomJS you may want to install your PhantomJS application as a Windows service. There are a few good reasons for this, but one is running a persistent PhantomJS web server.

If you are interfacing with PhantomJS from another application, it is simple enough to create a new instance of PhantomJS each time you need to use it (i.e. via <cfexecute> in ColdFusion). The problem is that this will result in multiple PhantomJS processes, one for each instance, which leads to unnecessary system overhead. Alternatively, you may want to keep a persistent instance of PhantomJS running as a Windows service to handle multiple requests from your application.

For this to be practical, the persistent instance of PhantomJS has to be able to accept requests and provide responses to your application. In my case, I created a PhantomJS web server application to achieve this. It listens to HTTP requests on an obscure port only available internally. The PhantomJS website has some helpful examples for setting such a web server up. From there, my ColdFusion application simply needs to interface with my PhantomJS server via HTTP.

None of this is helpful unless the PhantomJS web server is up and running. By registering the PhantomJS application as a Windows service, we can ensure it is up and running at all times. We can also stop it, start it, and restart it as needed.

Before proceeding, note that this process requires changes to your registry. I hold no responsibility for changes you make. All changes are your own responsibility. I have successfully used this process on a both a Windows 7 64bit install and a Windows Server 2008 R2 64bit install.

Ensure you can run your PhantomJS application from command line without failure before turning it into a Windows service to begin with. For example, from command line: C:\apps\your-application\bin\phantomjs.exe phantom.your-script.js <port-number>. Where <port-number> represents the port number your phantom.your-script.js is setup to accept as an argument

Download necessary tools from: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en
  • I suggest installing to C:\apps\rktools\
  • We will need these exe files:
    • C:\apps\rktools\srvany.exe
    • C:\apps\rktools\instsrv.exe

Run at CMD: C:\apps\rktools\INSTSRV.EXE "Phantom JS" C:\apps\rktools\SRVANY.EXE
  • "PhantomJS" is an arbitrary service name. Call it whatever you like. You can use spaces here, but maintain the quotes.

Open regedit.exe
  • Navigate to HKEY_LOCAL_MACHINE > SYSTEM > CurrentControlSet > Services > "Phantom JS" (your service name)
  • Right-click on the service name > New > Key
    • Name the key "Parameters"
  • Right-click on the Parameters key > New > String Value
    • Name the String value "Application"
    • Right-click "Application" > Modify
      • Set the value to: "C:\apps\your-application\bin\phantomjs.exe" phantom.your-script.js <port-number>
        • Make sure the path to the exe is quoted and the arguments are not. This should essentially be the same string you can pass to the CMD line to run your PhantomJS application but with quotes around the exe path. Again, <port-number> represents the port number your phantom.your-script.js is setup to accept as an argument
  • Right-click on the Parameters key > New > String Value
    • Name the String value "AppDirectory"
    • Right-click "AppDirectory" > Modify
      • Set the value to: C:\apps\your-application\bin\
        • This is the path to your application folder containing the PhantomJS exe and your PhantomJS script.

Your entries should look something like this:



Open services.msc and you should see your new windows service present. It is set to auto-start by default, but go ahead and start it for the first time to ensure it runs without failure.