C# 强制TopShelf服务的单个实例

C# 强制TopShelf服务的单个实例,c#,windows-services,single-instance,topshelf,C#,Windows Services,Single Instance,Topshelf,我正在使用TopShelf托管我的windows服务。这是我的设置代码: static void Main(字符串[]args) { var host=HostFactory.New(x=> { x、 服务(s=> { s、 ConstructUsing(name=>newmyservice()); s、 开始时(tc=>tc.Start()); s、 停止时(tc=>tc.Stop()); }); x、 RunAsLocalSystem(); x、 SetDescription(STR_ser

我正在使用TopShelf托管我的windows服务。这是我的设置代码:

static void Main(字符串[]args)
{
var host=HostFactory.New(x=>
{
x、 服务(s=>
{
s、 ConstructUsing(name=>newmyservice());
s、 开始时(tc=>tc.Start());
s、 停止时(tc=>tc.Stop());
});
x、 RunAsLocalSystem();
x、 SetDescription(STR_servicesdescription);
x、 SetDisplayName(STR_ServiceDisplayName);
x、 SetServiceName(STR_ServiceName);
});
host.Run();
}
我需要确保在同一时间只能运行我的应用程序的一个实例。目前,您可以将其作为windows服务和任意数量的控制台应用程序同时启动。若应用程序在启动期间检测到其他实例,它应该退出


我真的很喜欢基于的方法,但不知道如何使它与TopShelf一起工作。

只需将互斥代码添加到tc.Start()中,并在tc.Stop()中释放互斥代码,同时将互斥代码添加到控制台应用程序的主界面。

这对我来说很有效。事实证明它非常简单——互斥代码只存在于控制台应用程序的主方法中。以前,我对这种方法进行了假阴性测试,因为我在互斥体名称中没有“全局”前缀

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");
    }
}
private static Mutex Mutex=new Mutex(true,@“Global\{my guid here}”);
静态void Main(字符串[]参数)
{
if(mutex.WaitOne(TimeSpan.Zero,true))
{
尝试
{
var host=HostFactory.New(x=>
{
x、 服务(s=>
{
s、 ConstructUsing(name=>newmyservice());
s、 开始时(tc=>
{
tc.Start();
});
s、 停止时(tc=>tc.Stop());
});
x、 RunAsLocalSystem();
x、 SetDescription(STR_servicesdescription);
x、 SetDisplayName(STR_ServiceDisplayName);
x、 SetServiceName(STR_ServiceName);
});
host.Run();
}
最后
{
mutex.ReleaseMutex();
}
}
其他的
{
//Fatal(“已检测到正在运行MyService应用程序!-应用程序必须退出”);
}
}
更简单的版本:

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();
    }
}