views:

631

answers:

3

I need to know a reliable way I can determine the folder that a windows service was started from. The way of determining this seems to be different than the way you'd determine it in a WPF applciaiton.

More Details (optional reading):

I have an embedded sql database that is used by both a WPF application and a windows service.

During development, the relative path to the database has been different for both projects because they have been running from their own debug directories while accessing this same embedded database.

Now, I'm trying to create an installer. I've moved both the windows service executable and wpf applications executable to the same root directory.

In the wpf applciation, I'm successfully creating a database connection string that points to the embedded database, but in the windows service I am not successfully creating this connection string.

+3  A: 

Get your main assembly with Assembly.GetEntryAssembly. There, you'll have the Location property telling where your code is installed.

Note that the current directory of a service is c:\windows\system32 (assuming default install dir).

Timores
I'm unable to find the exact method/property you mention (GetEntryAssembly). Perhaps this is because I'm trying to access it from the code library instead of the service itself.
LonnieBest
GetEntryAssembly is a static method of Assembly. You need to add a 'using System.Reflection' to have IntelliSense show it.
Timores
+2  A: 

I think you are attacking the problem from the wrong direction. I would make the path to the database configurable in the config file for both the WPF app and the Windows Service. Then your code would simply build the connection string with the path from the config file.

Alternatively, you might think about using an environment variable and setting that environment variable in your installer.

Payton Byrd
The path has to be determined programmatically. Because the application could be installed on any machine. If I set a path in the config file, as you mention, how could I make sure that the path is correct for each place these application are installed, without manually configuring them for each installation?
LonnieBest
This would be a good place for a custom installation behavior to <strike>allow</strike> force the user to select the location of the database.
Payton Byrd
I don't think the user should have to know where the database is. Since it is an embedded database, used by both of my applications, I should figure out a way to determine the connection string programmatically. The database will be located right where the applicaiton is installed and then it is used by both applications.
LonnieBest
If you're sticking a database under %Program Files% on my system I'd be pissed. You should think about this from the perspective of your users. 99% may not care, but those of us who have a real disaster recovery plan will want to place important data in a location where we know it will get backed up appropriately.
Payton Byrd
Payton, the database is used for the two application to share certain data. None of the data is backup worthy; it is used as a collaborative memory space for the two applications to communicate with a degree of persistence between sessions. Where it is placed is perfectly fine. The priority is making it easy to use. Therefore I want to eliminate the user from having to do anything that I can automate. My applications should know where their database is; it is not a burden to push onto the user.
LonnieBest
+2  A: 

To get the directory that the windows service was installed in, you can use :

        private string GetExeDir()
    {
        System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
        string codeBase = System.IO.Path.GetDirectoryName(ass.CodeBase);
        System.Uri uri = new Uri(codeBase);
        return uri.LocalPath;
    }
Moe Sisko