开发者

Windows Service installation - current directory

this question is related to my previous one . I've written a service in C# and I need to make it's name dynamic and load the name from configuration file. The problem is that current directory while the service installer is invoked is the net framework 4 directory instead of the one that my assembly sits in.

Usin开发者_开发知识库g the line (which helps with the same problem, but while the service is already running) System.IO.Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);

sets the directory to

C:\Windows\Microsoft.NET\Framework\v4.0.30319

which was also the initial value.

How to get the right path?


try this one:

Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);


You can also try

Assembly.GetExecutingAssembly( ).Location

That also works if you're not referencing winforms or wpf


We had the same problem in a project i was working on but we took a different approach. Instead of using App.config files that has to be in the same path as the executable, we changed both the installer class and the Main entry point of the service.

We did this because we didn't want the same project files in different locations. The idea was to use the same distribution files, but with different service names.

So what we did was inside our ProjectInstaller:

private void ProjectInstaller_AfterInstall(object sender, InstallEventArgs e)
{
    string keyPath = @"SYSTEM\CurrentControlSet\Services\" + this.serviceInstaller1.ServiceName;
    RegistryKey ckey = Registry.LocalMachine.OpenSubKey(keyPath, true);
    // Pass the service name as a parameter to the service executable
    if (ckey != null && ckey.GetValue("ImagePath")!= null)
        ckey.SetValue("ImagePath", (string)ckey.GetValue("ImagePath") + " " + this.serviceInstaller1.ServiceName);
}

private void ProjectInstaller_BeforeInstall(object sender, InstallEventArgs e)
{
    // Configura ServiceName e DisplayName
    if (!String.IsNullOrEmpty(this.Context.Parameters["ServiceName"]))
    {
        this.serviceInstaller1.ServiceName = this.Context.Parameters["ServiceName"];
        this.serviceInstaller1.DisplayName = this.Context.Parameters["ServiceName"];
    }
}

private void ProjectInstaller_BeforeUninstall(object sender, InstallEventArgs e)
{
    if (!String.IsNullOrEmpty(this.Context.Parameters["ServiceName"]))
        this.serviceInstaller1.ServiceName = this.Context.Parameters["ServiceName"];
}

We used InstallUtil to instal our service like this:

[FramerokPath]\installutil /ServiceName=[name] [ExeServicePath]

Then, inside the Main entry point of your application, we checked the args attribute to get what was the installation name of the service that we setted inside the AfterInstall event.

This approach has some issues, like:

  • We had to create a default name for the service that was installed without the parameter. For instance, if no name was passed to our service, then we use the default one;
  • You can change the service name passed to our application to be different from the one that was installed.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜