views:

178

answers:

5

I'm writing a windows service in C# that spawns multiple instances of another application I am writing. There is a chance that the application can be installed anywhere on a machine. What is the best way to let the service know where the application is located?

+1  A: 

using System.IO; using System.Windows.Forms;

string appPath = Path.GetDirectoryName(Application.ExecutablePath)

Thats for an applications (above).

for an asp.net project:

using System.Web;

HttpContext.Current.Server.MapPath( "place arguments here" );
see_sharp_guy
This won't work in a service, which doesn't have forms
Treb
A service can reference windows forms without issue. The above line doesn't actually use any forms, and should be OK. But there are easier ways to get the codebase!
Marc Gravell
Sorry, misunderstood the question - I thought he wanted to get the location of the service.
Treb
+6  A: 

If you mean that the service starts a different app, then; options:

  • configure the service with a config file; put the path in there
  • put something in the registry during installation
  • use something akin to COM/COM+ registrations
  • consider the GAC if the other app is .NET (although I'm not a fan...)
  • environment variable?

Personally, I like the config file option; it is simple and easy to maintain, and allows multiple separate (side-by-side) service and app installs

Marc Gravell
I'd like to know more about utilizing the gac in this scenario, although I'm aware of the dangers how would this work? what about the config file, would it be embedded? if it's not embedded where should a config for a service exist?
Firoso
I'll probably end up going with the config file method, but I'd also like to know more about using the GAC in this way as well.
MGSoto
+7  A: 

If you need to locate the folder your service is installed to you can use the following code

this.GetType().Assembly.Location

If you need to locate the folder some other application is installed to you should make a request to windows installer

[DllImport("MSI.DLL", CharSet = CharSet.Auto)]
private static extern UInt32 MsiGetComponentPath(
    string szProduct,
    string szComponent,
    StringBuilder lpPathBuf,
    ref int pcchBuf);

private static string GetComponentPath(string product, string component)
{
    int pathLength = 1024;
    StringBuilder path = new StringBuilder(pathLength);
    MsiGetComponentPath(product, component, path, ref pathLength);
    return path.ToString();
}
Mike
+1  A: 

System.Environment.CurrentDirectory

Josh McDannel
+1  A: 

Write a registry variable during installation, this way when delivering an upgrade you can read back the value previously written and default to the users previously selected folder.

sascha