[英]How to prevent multiple instances of a program running at the same time?
So I've created a program (not using forms) so it is a clean class, not a form. 所以我创建了一个程序(不使用表单),因此它是一个干净的类,而不是表单。 So, when the program starts, I want it to check Processes and if another one is found, kill itself. 因此,当程序启动时,我希望它检查进程,如果找到另一个进程,则自行终止。 I have tried this... 我试过这个......
static void checkDupe()
{
string RunningProcess = Process.GetCurrentProcess().ProcessName;
Process[] processes = Process.GetProcessesByName(RunningProcess);
if (processes.Length > 1)
{
Process.GetCurrentProcess().Kill();
}
}
Look at using a Mutex : 看看使用Mutex :
class Program
{
static Mutex _m;
static bool IsSingleInstance()
{
try
{
// Try to open existing mutex.
Mutex.OpenExisting("PERL");
}
catch
{
// If exception occurred, there is no such mutex.
Program._m = new Mutex(true, "PERL");
// Only one instance.
return true;
}
// More than one instance.
return false;
}
static void Main()
{
if (!Program.IsSingleInstance())
{
Console.WriteLine("More than one instance"); // Exit program.
}
else
{
Console.WriteLine("One instance"); // Continue with program.
}
// Stay open.
Console.ReadLine();
}
}
The above example is taken from: 以上示例取自:
http://www.dotnetperls.com/mutex http://www.dotnetperls.com/mutex
it returns instance of running program by name 它按名称返回正在运行的程序的实例
private static Process RunningInstance()
{
var current = Process.GetCurrentProcess();
var procName = current.ProcessName.Replace(@".vshost", string.Empty);
var processes = Process.GetProcessesByName(procName);
return processes.FirstOrDefault(t => t.Id != current.Id && current.SessionId == t.SessionId);
}
This is copied form my other answer: Syncing between multiple instances of the same program 这是从我的另一个答案复制: 在同一程序的多个实例之间同步
Bellow you can find code that simplifies checking multiple instances as well as allow to transfer starting params from second instance to first one. 在Bellow中,您可以找到简化检查多个实例的代码,并允许将起始参数从第二个实例转移到第一个实例。
/// <summary>
/// Enforces single instance for an application.
/// </summary>
public class SingleInstance : IDisposable
{
#region Fields
/// <summary>
/// The synchronization context.
/// </summary>
private readonly SynchronizationContext synchronizationContext;
/// <summary>
/// The disposed.
/// </summary>
private bool disposed;
/// <summary>
/// The identifier.
/// </summary>
private Guid identifier = Guid.Empty;
/// <summary>
/// The mutex.
/// </summary>
private Mutex mutex;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="SingleInstance"/> class.
/// </summary>
/// <param name="identifier">
/// An identifier unique to this application.
/// </param>
/// <param name="args">
/// The command line arguments.
/// </param>
public SingleInstance(Guid identifier, IEnumerable<string> args)
{
this.identifier = identifier;
bool ownsMutex;
this.mutex = new Mutex(true, identifier.ToString(), out ownsMutex);
this.synchronizationContext = SynchronizationContext.Current;
this.FirstInstance = ownsMutex;
if (this.FirstInstance)
{
this.ListenAsync();
}
else
{
this.NotifyFirstInstance(args);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="SingleInstance"/> class.
/// </summary>
/// <param name="identifier">
/// An identifier unique to this application.
/// </param>
public SingleInstance(Guid identifier)
: this(identifier, null)
{
}
#endregion
#region Public Events
/// <summary>
/// Event raised when arguments are received from successive instances.
/// </summary>
public event EventHandler<OtherInstanceCreatedEventArgs> OtherInstanceCreated;
#endregion
#region Public Properties
/// <summary>
/// Gets a value indicating whether this is the first instance of this application.
/// </summary>
public bool FirstInstance { get; private set; }
#endregion
#region Implemented Interfaces
#region IDisposable
/// <summary>
/// The dispose.
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#endregion
#region Methods
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">
/// True if managed resources should be disposed; otherwise, false.
/// </param>
protected virtual void Dispose(bool disposing)
{
if (this.disposed)
{
return;
}
if (disposing)
{
if (this.mutex != null && this.FirstInstance)
{
this.mutex.WaitOne();
this.mutex.ReleaseMutex();
this.mutex = null;
}
}
this.disposed = true;
}
/// <summary>
/// Fires the OtherInstanceCreated event.
/// </summary>
/// <param name="arguments">
/// The arguments to pass with the <see cref="OtherInstanceCreatedEventArgs"/> class.
/// </param>
protected virtual void OnOtherInstanceCreated(OtherInstanceCreatedEventArgs arguments)
{
EventHandler<OtherInstanceCreatedEventArgs> handler = this.OtherInstanceCreated;
if (handler != null)
{
handler(this, arguments);
}
}
/// <summary>
/// Listens for arguments on a named pipe.
/// </summary>
private void Listen()
{
try
{
using (var server = new NamedPipeServerStream(this.identifier.ToString()))
{
using (var reader = new StreamReader(server))
{
server.WaitForConnection();
var arguments = new List<string>();
while (server.IsConnected)
{
arguments.Add(reader.ReadLine());
}
this.synchronizationContext.Post(o => this.OnOtherInstanceCreated(new OtherInstanceCreatedEventArgs(arguments)), null);
}
}
// start listening again.
this.Listen();
}
catch (IOException)
{
// Pipe was broken, listen again.
this.Listen();
}
}
/// <summary>
/// Listens for arguments being passed from successive instances of the applicaiton.
/// </summary>
private void ListenAsync()
{
Task.Factory.StartNew(this.Listen, TaskCreationOptions.LongRunning);
}
/// <summary>
/// Passes the given arguments to the first running instance of the application.
/// </summary>
/// <param name="arguments">
/// The arguments to pass.
/// </param>
private void NotifyFirstInstance(IEnumerable<string> arguments)
{
try
{
using (var client = new NamedPipeClientStream(this.identifier.ToString()))
{
using (var writer = new StreamWriter(client))
{
client.Connect(200);
if (arguments != null)
{
foreach (string argument in arguments)
{
writer.WriteLine(argument);
}
}
}
}
}
catch (TimeoutException)
{
// Couldn't connect to server
}
catch (IOException)
{
// Pipe was broken
}
}
#endregion
}
/// <summary>
/// Holds a list of arguments given to an application at startup.
/// </summary>
public class OtherInstanceCreatedEventArgs : EventArgs
{
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="OtherInstanceCreatedEventArgs"/> class.
/// </summary>
/// <param name="args">
/// The command line arguments.
/// </param>
public OtherInstanceCreatedEventArgs(IEnumerable<string> args)
{
this.Args = args;
}
#endregion
#region Public Properties
/// <summary>
/// Gets the startup arguments.
/// </summary>
public IEnumerable<string> Args { get; private set; }
#endregion
}
Then in your main class you can create instance of of class that will stay until aplication is running. 然后在您的主类中,您可以创建类的实例,该实例将保留到应用程序运行之前。 You can check if other instance is created by FirstInstance
property, And get notified of other instance created by OtherInstanceCreated
event. 您可以检查FirstInstance
属性是否创建了其他实例,并获得OtherInstanceCreated
事件创建的其他实例的通知。
Same mutex idea, but simpler code: 相同的互斥锁的想法,但更简单的代码:
bool SingleInstance;
var mut = new Mutex(true,"UniqueName", out SingleInstance);
if (SingleInstance) {
//Run
} else {
//Exit
}
When application exists, mutex is destroyed, no need to release it or dispose it or anything. 当应用程序存在时,互斥锁被破坏,无需释放或处置它或任何东西。
(AFAIK) (据我所知)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.