Monthly Archives: June 2012

String Split – Really!?

I’ve seen a lot of code recently where the developer has written something like this:

            string cars = "Honda;BWM;Mazda;Audi";
            string[] carsArray = cars.Split(new char[] {';'});

Although the method signature specifies a char array, it’s just as easy and effective to write:

            string cars = "Honda;BWM;Mazda;Audi";
            string[] carsArray = cars.Split(';');

Or if you like to use constants, as I do:

    class Program
    {
        private const char SemiColon = '\x003B';

        static void Main(string[] args)
        {
            string cars = "Honda;BWM;Mazda;Audi";
            string[] carsArray = cars.Split(SemiColon);

            carsArray.ToList().ForEach(Console.WriteLine);

            Console.WriteLine("{0}Press any key to kill ...", Environment.NewLine);
            Console.ReadLine();
        }
    }

Thank you. Good night.

How to Write a Service to Run Under a Custom User Account

So you want to write a Windows Service which runs under a particular user account, but you’re having trouble figuring out how to configure it to use your custom user? This is the small hurdle I faced a couple of weeks back.

To start at the beginning, I wanted to write a Service which detects when iTunes downloads podcast files via its podcast update function. It then copies details of the newly downloaded podcast into a database. I wanted to lock this service down, by making it run under a particular custom user account, which will have its permissions completely locked down to a bare minimum (as is best practice).

I’ve written services before, so I got right up to the point where you tell it which user account to run under. I clicked the dropdown box (pictured in Figure 1), selected User from the choices and then wondered to myself, “Where do I put the authentication credentials.”

Figure 1

This was not immediately obvious. And surprisingly enough, my various books and Google were not forthcoming. This, I found surprising, given the fact that this should be a reaonably frequent scenario.

Lets take a step back for a moment. On the design surface displayed in Figure 1, you can see a PodcastWatcherServiceInstaller component (derives from¬†System.ServiceProcess.ServiceInstaller) and a PodcastWatcherServiceProcessInstaller component (derives from System.ServiceProcess.ServiceProcessInstaller). There is 1 PodcastWatcherServiceInstaller for every service installed as part of the package and a single PodcastWatcherServiceProcessInstaller for the executable which will install all those services. In most cases, there will be only 1 service installed with any given installment package, so it’s usually a 1-to-1 mapping. So where do the user credentials fit in?

As can be seen from the above screen shot, the GUI does not provide any input fields for usernames or passwords. With some extensive reading of MSDN and some trial and error, I discovered the solution. The class in which those two components are members is the ProjectInstaller class. Just press F7 at the designer view and you will be presented with the code. It is in the code that you can specify the Username and Password for the User:

    [RunInstaller(true)]
    public partial class ProjectInstaller : System.Configuration.Install.Installer
    {
        public ProjectInstaller()
        {
            InitializeComponent();

            PodcastWatcherServiceProcessInstaller.Account = ServiceAccount.User;
            PodcastWatcherServiceProcessInstaller.Username = @"PACEMAN\PodcastWatcherUser";
            PodcastWatcherServiceProcessInstaller.Password = "s0m3pa55w0rd";
        }
    }