Some of my blog entries are just to remind myself how to do things later–and on several occasions they’ve been useful in that regard. I hope they are also useful to others that may encounter similar struggles. This is another one of those articles which I will likely refer back to at some point.
I’ve been doing more and more with .NET and using Oxygene makes the transition from Delphi a little more familiar. One of the things I’ve been working on lately is a set of plug-ins to a Delphi application that provide additional functionality. And with Hydra, I can write those plug-ins in either Delphi or Oxygene. Recently, I wanted one of my plug-ins to talk to a service on a remote server. The first step, of course, is to write the service for the remote server and learn how to get it installed.
Because Microsoft Visual Studio Community 2013 has such a large developer base, there are many resources to help you accomplish this (that’s the beauty of working in .NET rather than Delphi). But just a few nuances here and there for someone that doesn’t do this very often slowed me down a little. Finding just the right web reference or book chapter takes time, so once I find that, I tend to want to write it down.New Project
First of all, Visual Studio makes it pretty simple to get started: just select the “Windows Service” new project template.
This gives you a project to start with that includes Main.pas, the main section of the code you’ll be working with, Program.pas, which you can likely ignore but is necessary, and ProjectInstaller.pas.
The first thing to do is right-click on Main and View Designer. Look in the Properties window and click on Add Installer, a small link at the bottom. This adds a couple of components to the ProjectInstaller and allows you to easily name and describe your service.Service Properties
Now in the ProjectInstaller designer view, click on the serviceInstaller component and set the DisplayName and Description properties. These will show up in the Services control panel after it’s installed. Here’s also where you can set the StartType (Manual, Automatic, or Disabled) and other properties affecting how the service behaves with Windows. If you then view the code for ProjectInstaller.Designer.pas, you’ll see the properties you set listed in the InitializeComponent method.
Before you leave the ProjectInstaller, you need to check one more thing. Look at the properties for the other component in designer mode, serviceProcessInstaller. An important property is Account. By default, it’s set to User, but in most cases it can be either LocalService or LocalSystem. I’ll leave it to the reader to research the differences and choose what is most appropriate for your situation. For this simple test, setting it to LocalService is easiest.Event Logging
Since a service does not typically interact with users but runs silently in the background, it’s a good idea to provide some way to check to make sure it is running. There is an automatic way of doing this and all it takes is one line in the constructor of Main.pas:
AutoLog := true;. This will add to the System Event Log when the service is started, stopped, paused, or resumed. You can add your own custom logging by using the EventLog component on by rolling your own.
Now even though this service doesn’t do anything useful, it’s got the basics to be compiled, run, installed, and started with logging to see it actually happen. So compile the project and move to the final step.Install the Service
When a service is ready to install, use the command-line utility InstallUtil. This utility comes with the .NET framework. Normally, there is no path to the .NET framework tools, but both Visual Studio and Oxygene provide command shells you can launch that provide the path. However, you need to know which version of the .NET framework you used to build your project because the shells are specific to the version of the framework and if you run the wrong one, you’ll get errors. Oxygene comes with one for .NET 2.0 but the default framework for new projects (as of this writing) is .NET 4.0. I have copied the batch file that is installed with Oxygene (
C:\Program Files (x86)\RemObjects Software\Oxygene\bin\OxygenePrompt.bat) and separated them so I now have one for each of the two framework versions. (By the way, to tell which version your project is using, view the Application tab of the project’s properties and you’ll see it under Target Framework.) Once you have the correct command shell ready, be sure to Run as Administrator because standard users cannot install/uninstall Windows services.
With the command shell running as administrator, navigate to the bin\Release folder for your service and type
InstallUtil MyServiceName.exe (where “MyServiceName” is the name of your project). Open the Services control panel (or refresh if it was already open) and you should see your new service. You can start or stop it just like other services (although if you’ve followed this example, it doesn’t yet do anything once started).
Now that the service is built and installed, start the service then go to the Windows Event Viewer. You should see events in both the Application and System sections of the Windows Logs.
Now, it’s time to go back to Main.pas and add some useful code when it starts!
I’m a long time Delphi user and have taken advantage of the Object Repository quite a bit. It’s really handy to take a unit or project that might be useful somewhere else but in a slightly different form and add it to the repository. Later, when you need to use that bit of code, you can select it from the repository right from within Delphi and it will make a copy of that code in your new project.
If you’re wondering why not use a library or even the popular Delphi IDE plug-in, GExperts, with its “librarian” feature, I do. A code library is static and GExperts is best for small code snippets. But sometimes you just need to copy and modify a large chunk of code. For this, I have found Delphi’s Object Repository to be a great tool. And actually, anyone who creates projects in Delphi’s IDE uses the standard repository objects that come with Delphi, namely the “New Project,” perhaps without realizing it.
I write a lot of plug-in modules for a point-of-sale software called Retail Pro. Its plug-in API requires building COM servers that adhere to a set of interfaces. There’s a lot of structure to be setup for each plug-in and several properties that interact to accomplish a retailer’s goal. Each interface is typically implemented as a single Delphi unit and while it has the same basic structure (since it implements an interface) it will have different method implementations and property values. It’s hard to remember all the different nuances that each API call can have and how they can be used inside Retail Pro. So what I’ve done is create a repository unit for each interface and copied all the documentation for that interface into the unit using XML Documentation. Then I’ve added it to the Delphi Object Repository.
When I need to build a new plug-in for Retail Pro, I create a new plug-in project and then add the interface units I need to implement from the repository. This jump-starts my project with all the code in place, complete with documentation and even TODO items that I can just fill in and compile. Of course, the end solution involves quite a bit more than that, but a lot of work has been saved.
So, now that you’re convinced this is a cool tool to add to your collection, it should come with a little warning: it’s fairly easy to break and there’s not much documentation. There are a couple of references here and there that talk about Delphi’s repository setup when it’s installed, but it took some searching to find out where additional items added by the user are stored.
The folder for Delphi’s built-in repository (that doesn’t change) is in its installation folder under
Program Files (x86), or if you’re still on a 32-bit system, just
Program Files. Since Windows Vista came out with it’s increase protection of the Program Files folders, the editable copy of the repository is located in a user directory, probably under either
%APPDATA%\Embarcadero\BDS\<version>, depending on your version of Delphi, and is named
RADStudioRepository.xml. (Really old versions of Delphi stored these settings in delphi32.dro under Delphi’s bin folder.)
The structure of the RADStudioRepository.xml file can, of course, be changed with your favorite text or XML editor. That in itself could break the object repository, but it can actually be done using Delphi itself. (Dislaimer: I’ve only tested this with Delphi 2010, not anything newer. It’s possible the following has been prevented in newer versions of the IDE.) When you’re adding an item, you can optionally specify an icon. The help for this screen says that you can use a bitmap of any size but it will be cropped to 60 x 40 pixels. I happened to choose 24×24 bit icons for several items added one day. I noticed immediately the
New Item... menu option no longer showed the category of repository items I had just added. Restarting Delphi, I got an “invalid image size” error every time I selected
File | New | Other... which rendered all my user entries in the repository inaccessible.
I looked at Delphi’s own repository settings and saw that many of them were 32×32 bit. So I manually edited the XML file for the entries I had entered and changed them to point to 32×32 bit icons, restarted Delphi, and it worked. (You can also simply leave the icon path empty in the XML or not add one in the first place–the icon is optional.)
Surprisingly, an invalid path or filename to the icon does not break the repository, it’s just when it tries to actually load an icon with a resolution it’s not expecting (or one that’s evidently not supported) that causes it to throw up an error.
I’ve been spending a lot of my spare time with RemObjects products (mostly Oxygene and Hydra) over the last several months and haven’t kept up my blog on those subjects like I intended. But another distraction is taking an increasing interest as more of a fun hobby than a dire need that will make me money.
I got a Raspberry Pi.
Actually, this is a picture of my second Raspberry Pi and there are two more on the way.
Now, I probably don’t have to explain what this is to most readers, but just in case someone doesn’t know, these are small, inexpensive single-board, system-on-a-chip computers that are designed to be easy to connect to a wide variety of devices, sensors, and controllers. They’re great fun to tinker with, learn on, and experiment with–and there are many, many web sites with instructions to build everything from a Lego robot to a home surveillance system to a multi-node, password-hacking super computer array!
My interests are fairly modest: I simply want to have a remote camera to watch the front porch from my back-of-the-house office. Oh, and it would be cool to set next year’s Christmas lights to music. And I might setup a torrent server. And maybe a voice-activated office lighting controller. And… My family might never see again.
I will likely blog some of what I do but one of the first things I want to write down so I don’t forget is actually a fix for an annoyance in Linux. The Raspberry Pi computers run Linux, of course, and every Linux distribution I’ve tried comes setup to blank the screen after a bit. Now this is good if you have a computer that you walk away from and forget to shut down or something, but the projects I have slated would either not have a screen attached at all or would need to have a small screen that is always on. So the first thing I had to figure out was how to disable the screen saver. This turned out to be surprisingly difficult to get right.
There are two parts: 1) the command-line, and 2) the graphical user interface. Everything in Linux can be customized and different from one system to another, so whatever I write here must include the disclaimer that it may be different on your system. If you install Raspbian, a popular distribution for Linux on Raspberry Pi, then the following should work for you. In any case, the main reason for me documenting it here is so that I will remember how to set it up on subsequent installs!
First the command line. This, more than anything, should be standard for every Linux system that runs the Bash command line shell (and should be simple to adjust to a different one). The system-wide start file,
/etc/bash.bashrc, is where you want to add one line:
setterm -blank 0 -powerdown 0
This will 1) set the time interval to blank the screen (-blank) to zero which will disable it, and 2) keep the monitor from powering down (-powerdown). You may also need to use -powersave, but these two have worked for me on a couple of monitors.
Next, the graphical user interface (GUI) where you have friendly icons and can use the mouse has its own screen saver, separate from the command-line terminal. The GUI environment on Linux is called X and there are quite a variety of settings. On top of that, you have the desktop window environment. Since Raspbian comes default with LXDE, I’ll mention only this one. The start-up file for LXDE is:
There are two things to do: 1) disable the screen saver, and 2) disable the EnergyStar features.
The first part seems easy enough, simply comment out the line that starts the screen saver (you can just as well delete it if you want; I keep it there to remind me what it had been if I ever decide I want to turn it back on):
This, you might think, should be enough to disable the screen saver. And, well, it does. However, the X11 system has additional built-in screen-saver capabilities, so you need to do a couple of extra steps:
@xset s noblank
@xset s off
Finally, disable EnergyStar features of your monitor so it won’t go into a power-save mode even though your screen saver is off:
There are numerous forums and blogs all over the internet with various ways to do this and indeed they work for those situations. After trying several, I settled on the steps above and wrote them down so that it will save me time looking them up.
Hopefully, it helps you as well!
I recently watched most of a dotnetConf, a virtual conference on .NET hosted by Microsoft. All the sessions were recorded and there’s a lot of good and relevant content.
I was programming Win32 apps in Delphi while listening and I felt myself yearning for the cool technologies they were discussing. Yeah, Delphi has grown up a bit, but it’s no longer the leader, it’s following and getting further and further behind the rest of the development community.
Several of the sessions concentrated on ASP.NET and one in particular caught my eye because it’s a framework that makes it easy to build not just web sites, but web apps that dynamically resize for a variety of form factors with cool techniques like shrinking a list of menu items down into a “hamburger” icon. The name implies it’s an extension to ASP.NET itself: ASP.NET Web API.
ASP.NET has much better and easier support for encrypting web pages (which you SHOULD DO for any login or data-centric site).
Testing and deploying ASP.NET web sites has been made much easier than in “the old days.” Not only are the tools simpler, but Microsoft provides built-in connections for Azure, not surprisingly. But if you want to make sure your site will work on a remote domain name without actually deploying to a remote site, there’s a nifty domain name called, localtest.me, that anyone can use. Read about it–it’s genius!
Finally, I learned about another Microsoft resource, Microsoft Virtual Academy. There are many free courses to help get you started in many different subject areas–progrmaming Windows phones, SQL Server, business strategies, HTML5, licensing, virtualization, and many more.
These will be great sites that I visit often as I get more and more into .NET for my own enjoyment and education. I’m using the RemObjects suite of .NET tools which is a great way to shift my Delphi experience to a more popular development environment. Plus, with Hydra, I can blend the two technologies into one application and slowly swap out modules until I’ve completely migrated the application. I don’t know if I’ll ever need to completely replace Delphi as I’ll more likely build something in ASP.NET using DataAbstract with RemObject’s Relativity Server hooked to my ElevateDB database. But at least I can connect to complicated APIs like Amazon Web Services from a Delphi application right now! That’s something I simply could not do before.