Running RavenDb embedded for .NET 3.5

The application I’m developing will be a stand-alone client application. Nothing fancy and business-critical, so RavenDb might be overkill, but I’m attracted to the ease of use.

The application will be installed by non-technical users, so I’m not too fond of the idea of running RavenDb as a service. This will require the users to enter their Administrator password, which could frighten them. I could choose the embedded option, but as I don’t have Visual Studio 2010 yet, I can’t develop for .NET 4. So I want to have a sort of embedded option for RavenDb *using *.NET 3.5.

I want to run RavenDb in the background while my application runs, and shut it down when the user exits the application. Luckily, you can start RavenDb.exe as a console application. But then the user would see a console launching, which I don’t want either.

So this is what I did.

public static void StartRavenDb()
{
    var ravenDbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RavenDb/RavenDb.exe");
    ProcessStartInfo startInfo = new ProcessStartInfo(ravenDbPath);
    startInfo.UseShellExecute = false;
    startInfo.CreateNoWindow = true;
    Process.Start(startInfo);
}

This starts RavenDb, but avoids creating a console window. When my application stops I can call:

public static void StopRavenDb()
{
    System.Diagnostics.Process.GetProcessesByName("RavenDb")[0].Kill();
}

This could be a problem if RavenDb is already running for another application. First, because you can only start one instance of RavenDb.exe, and then I could be killing the process used by another applicaiton.

However, the possibility is very low, especially with my target users, but I will have to look into this. One other thing to check is whether this can do any harm, as the console application of RavenDb is meant for debugging purposes.

UPDATE: I asked Ayende and he was kind enough to answer, saying this is indeed a viable option, but I’d better stop the process gracefully instead of killing it.

UPDATE 2: closing RavenDb is better than killing it, so I changed the StartRavenDb and StopRavenDb methods to:

public static void StartRavenDb()
{
    var ravenDbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RavenDb/RavenDb.exe");
    ProcessStartInfo startInfo = new ProcessStartInfo(ravenDbPath);
    startInfo.UseShellExecute = false;
    startInfo.CreateNoWindow = true;
    startInfo.RedirectStandardInput = true;
    _ravenDb = Process.Start(startInfo);
}

public static void StopRavenDb()
{
    var inputStream = _ravenDb.StandardInput;
    inputStream.Write("\r\n");
}

Apparently, I have to put the result of Process.Start in a variable to keep a reference to it. Also, to avoid the ‘StandardIn has not been redirected’ exception, I have to set the RedirectStandardInput property to true.

To stop RavenDb, I just send “\r\n” to the standard input of RavenDb. Thanks to Ayende for pointing out the obvious.