Home > Uncategorized > Using External .NET Config Files in a Windows Service

Using External .NET Config Files in a Windows Service

The .NET platform provides an easy way to configure your .NET application using an xml configuration file. At design time, the file is named “App.Config”. When you build your project (console application, Windows service, etc.), the file is renamed to the form [ProgramName].exe.config. The file is deployed in the same directory as the executable. At runtime, the file is automatically picked up from the current directory by the Configuration class.

The single App.config file works pretty well for simple stuff, but at some point it gets unwieldy and you want to separate the configuration into separate files. For example. log4net and Spring.NET both provide mechanisms for using external config files. In a normal deployment scenario (e.g. a console application), it just works.

Often, trouble arises when combining these external configuration files with a Windows service deployment. The built-in configuration classes seem to locate the main config file well enough, but the external files cannot be located. They are attempted to be loaded from %SystemRoot%\System32. Why? This is the location of the net command, which is the host process for the service. I suspect the implementers of the external configuration files refer to the CurrentDirectory of the process, instead of the file location of the executable module.

You can fix the problem by setting the CurrentDirectory of the process:

<!–
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Envy Code R VS;}}{\colortbl;??\red0\green0\blue0;\red227\green213\blue193;\red64\green0\blue128;\red1\green0\blue1;\red46\green83\blue209;\red48\green95\blue182;\red37\green146\blue65;\red163\green21\blue21;}??\fs24 \cb2\highlight2 \cf3 var\cf0 \cf4 process\cf0 \cf5 =\cf0 \cf6 Process\cf5 .\cf4 GetCurrentProcess\cf0 ();\par ?? \cf3 if\cf0 (\cf4 process\cf5 .\cf4 MainModule\cf0 \cf5 !=\cf0 \cf3 null\cf0 )\par ?? \{\par ?? \cf3 string\cf0 \cf4 newFilePath\cf0 \cf5 =\cf0 \cf4 process\cf5 .\cf4 MainModule\cf5 .\cf4 FileName\cf5 .\cf4 Substring\cf0 (\cf7 0\cf0 ,\par ?? \cf4 process\cf5 .\cf4 MainModule\cf5 .\cf4 FileName\cf5 .\cf4 LastIndexOf\cf0 (\cf8 @”\\”\cf0 ));\par ?? \cf6 Directory\cf5 .\cf4 SetCurrentDirectory\cf0 (\cf4 newFilePath\cf0 );\par ?? \}}
–>

   25 var process = Process.GetCurrentProcess();

   26 if (process.MainModule != null)

   27 {

   28     string newFilePath = process.MainModule.FileName.Substring(0,

   29         process.MainModule.FileName.LastIndexOf(@”\”));

   30     Directory.SetCurrentDirectory(newFilePath);

   31 }

If you like, you can put this code into the OnStart method of your service. But you might need the info before that. In that case, put the code as early as possible.

 

Credit goes to Jose Joye, who posted this idea back in 2005.

Reblog this post [with Zemanta]
Categories: Uncategorized
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 124 other followers