Class SingleInstance
- Namespace
- McServerLauncher.Services
- Assembly
- McServerLauncher.dll
Keeps the app to one running copy per user, and lets a second launch bring the first one back to the front instead of opening a window of its own.
public sealed class SingleInstance : IDisposable
- Inheritance
-
SingleInstance
- Implements
- Inherited Members
Remarks
Two copies of the launcher is not merely untidy: each one starts its own child server processes, its own wake-on-demand listeners and its own idle timers, and neither can see what the other is doing. The second window shows a server as stopped while the first has it running, so Start looks available — and pressing it means two JVMs writing the same world folder, which is how worlds get corrupted. This is a correctness guard, not a nicety.
The design is a lock file plus a named pipe. The lock file answers "is anyone else running?" with an exclusive open that the OS releases even if the process is killed, so a crash can never leave the app permanently unstartable — the failure mode a stale PID file would have. The pipe carries the "come to the front" nudge. Both work the same on Windows, Linux and macOS: .NET implements named pipes as Unix domain sockets where there are none.
Methods
Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()
SignalExistingInstance()
Asks the copy that is already running to show itself. True when it acknowledged.
public static bool SignalExistingInstance()
Returns
TryAcquire(out bool)
Claims the right to be the running copy.
public static SingleInstance? TryAcquire(out bool alreadyRunning)
Parameters
alreadyRunningboolTrue only when another copy demonstrably holds the lock. It is deliberately separate from a null return: "someone else is running" and "this machine would not let me find out" are opposite situations, and conflating them would either close a legitimate first launch or let a second one through.
Returns
- SingleInstance
The claim to hold open for the lifetime of the app, or null if it was not obtained — in which case
alreadyRunningsays whether that means "yield" or "carry on anyway".
Events
ActivationRequested
Raised on a background thread when another launch asks for the window.
public event Action? ActivationRequested