문제

I'm using TopShelf to host my windows service. This is my setup code:

static void Main(string[] args)
{
    var host = HostFactory.New(x =>
    {
        x.Service<MyService>(s =>
        {
            s.ConstructUsing(name => new MyService());
            s.WhenStarted(tc => tc.Start());
            s.WhenStopped(tc => tc.Stop());
        });

        x.RunAsLocalSystem();
        x.SetDescription(STR_ServiceDescription);
        x.SetDisplayName(STR_ServiceDisplayName);
        x.SetServiceName(STR_ServiceName);
    });

    host.Run();
}

I need to ensure that only one instance of my application can be running at the same time. Currently you can start it as windows service and any number of console apps simultaneously. If application detects other instance during startup it should exit.

I really like mutex based approach but have no idea how to make this working with TopShelf.

도움이 되었습니까?

해결책

This is what worked for me. It turned out to be really simple - mutex code exists only in Main method of console app. Previously I had a false negative test with this approach because I had no 'Global' prefix in mutex name.

private static Mutex mutex = new Mutex(true, @"Global\{my-guid-here}");

static void Main(string[] args)
{
    if (mutex.WaitOne(TimeSpan.Zero, true))
    {
        try
        {
            var host = HostFactory.New(x =>
            {
                x.Service<MyService>(s =>
                {
                    s.ConstructUsing(name => new MyService());
                    s.WhenStarted(tc =>
                    {
                        tc.Start();
                    });
                    s.WhenStopped(tc => tc.Stop());
                });
                x.RunAsLocalSystem();
                x.SetDescription(STR_ServiceDescription);
                x.SetDisplayName(STR_ServiceDisplayName);
                x.SetServiceName(STR_ServiceName);
            });

            host.Run();
        }
        finally
        {
            mutex.ReleaseMutex();
        }
    }
    else
    {
        // logger.Fatal("Already running MyService application detected! - Application must quit");
    }
}

다른 팁

A simpler version:

static void Main(string[] args)
{
    bool isFirstInstance;
    using (new Mutex(false, "MUTEX: YOUR_MUTEX_NAME", out isFirstInstance))
    {
        if (!isFirstInstance)
        {
            Console.WriteLine("Another instance of the program is already running.");
            return;
        }

        var host = HostFactory.New(x =>
        ...
        host.Run();
    }
}

Just add the mutex code to the tc.Start() and release Mutex in tc.Stop(), also add the mutex code to the Main of the console app.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top