Fix: NHibernate/log4net FileNotFoundException in a Windows Service
When using NHibernate or log4net inside a Windows Service you may encounter a FileNotFoundException on startup, even when the referenced assemblies or configuration files are sitting right next to the service executable. This happens regardless of which user context the service runs under — NetworkService, LocalSystem, or a dedicated account.
Key Takeaways
- Windows Services set their default working directory to
%WINDIR%\system32, not the directory containing the service executable. - NHibernate and log4net resolve configuration files relative to the working directory, so they look in the wrong place.
- The fix is a single line in
Main: setEnvironment.CurrentDirectoryto the directory of the entry assembly before anything else initialises. - Apply the fix before any NHibernate
SessionFactorybuild or log4netXmlConfiguratorcall.
The Problem
When a Windows Service starts, the operating system sets the process working directory to %WINDIR%\system32 (typically C:\Windows\System32). Libraries such as NHibernate and log4net that load configuration files using relative paths will attempt to open those files from System32 rather than from the service's own installation folder, producing a FileNotFoundException.
A common symptom is an exception in the event log similar to:
System.IO.FileNotFoundException: Could not load file or assembly 'hibernate.cfg.xml'
or one of its dependencies. The system cannot find the file specified.The Root Cause
The Windows Service Control Manager (SCM) does not inherit the working directory from wherever the binary lives. It always starts with %WINDIR%\system32. This is by design, and it affects any file-system operation that uses a relative path — not just NHibernate.
The Fix
Set Environment.CurrentDirectory at the very start of Main, before any library initialisation runs:
static void Main(string[] args)
{
// Set the working directory to the service's own folder.
// Windows Services default to %WINDIR%\system32, which causes
// NHibernate and log4net to fail when loading config files.
Environment.CurrentDirectory = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetEntryAssembly().Location);
// ... remainder of service startup
}This must appear before any call to build an NHibernate SessionFactory, configure a log4net appender, or open any other file by relative path.
Solution Architect with 30 years in cloud infrastructure, security, identity, and .NET engineering.