I'd like to use the Topshelf instance name as

2019-05-01 10:35发布

问题:

When creating an instance of a service using TopShelf I'd like to be able to access the service instance name(which may have been set on the command line during installation as a service; which means I don't have direct access to it) to be able to use that as a property for the log file name in Log4Net.

In the example code below we set various properties which are available to use for logging in the global context. I'd love to be able to set the Service instance name here also; but can't seem to be able to get access to it during host initialization.

Anyone any suggestions as to how I could access the service instance name value at run time with Topshelf.

The example below is part of a common function which all our services use to start a service using Topshelf.

public static TopshelfExitCode Run(Func<IConsumerController> controllerFactory,
    string serviceName,
    string serviceDescription)
{
    // Initialise the Global log4net properties so we can use them for log file names and logging when required.
    log4net.GlobalContext.Properties["custom-assembly"] = System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);
    log4net.GlobalContext.Properties["custom-processname"] = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
    log4net.GlobalContext.Properties["custom-process-id"] = System.Diagnostics.Process.GetCurrentProcess().Id;
// WOULD LIKE ACCESS TO THE SERVICE INSTANCE NAME HERE
    var logFileInfo = new System.IO.FileInfo(".\\Log.config");
    log4net.Config.XmlConfigurator.Configure(logFileInfo);

    var host = HostFactory.New(r =>
    {
        var controller = controllerFactory();
        r.Service<ConsumerService>( () => new ConsumerService(controller));
        r.SetServiceName(serviceName);
        r.SetDescription(serviceDescription + " © XYZ Ltd. 2012");
        r.SetDisplayName(serviceDescription + " © XYZ Ltd. 2012");
        r.StartAutomatically();
        r.EnablePauseAndContinue();
        r.RunAsLocalSystem();
    });
    return host.Run();
}

回答1:

The instance name is passed on the command line, you can access the command line arguments and pull it from there. This might take a little tweaking, but if you look at the ServiceInstaller you can see how we adjust the command path via registry editing once the service is installed.



回答2:

The HostSettings are passed to the service factory, which contains the InstanceName as a property. You should use that to initialize the log appender you want to add to log4net.