Last active
March 5, 2019 13:52
-
-
Save LGM-AdrianHum/d16a6b49d1b7644b2b9f88f85db2d41e to your computer and use it in GitHub Desktop.
Single Instance With Parameter Passing for WPF 4.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void Application_Startup(object sender, StartupEventArgs e) | |
{ | |
if (SingleInstance.IsFirstInstance) | |
{ | |
SingleInstance.ArgumentsReceived += SingleInstanceParameter; | |
SingleInstance.ListenForArgumentsFromSuccessiveInstances(); | |
// Do your other app logic | |
} | |
else | |
{ | |
// if there is an argument available, fire it | |
if (e.Args.Length > 0) | |
{ | |
SingleInstance.PassArgumentsToFirstInstance(e.Args[0]); | |
} | |
Environment.Exit(0); | |
} | |
} | |
static void SingleInstanceParameter(object sender, GenericEventArgs e) | |
{ | |
// Inform app of new arguments | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Your.App | |
{ | |
using System; | |
public class GenericEventArgs<TEventDataType> : EventArgs | |
{ | |
/// <summary> | |
/// Gets or sets the data. | |
/// </summary> | |
/// <value>The data.</value> | |
public TEventDataType Data { get; set; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Your.App | |
{ | |
using System; | |
using System.IO; | |
using System.IO.Pipes; | |
using System.Threading; | |
using System.Threading.Tasks; | |
public class SingleInstance : IDisposable | |
{ | |
private readonly bool ownsMutex; | |
private Mutex mutex; | |
private Guid identifier; | |
/// <summary> | |
/// Occurs when [arguments received]. | |
/// </summary> | |
public event EventHandler<GenericEventArgs<string>> ArgumentsReceived; | |
/// <summary> | |
/// Initializes a new instance of the <see cref="SingleInstance"/> class. | |
/// </summary> | |
/// <param name="id">The id.</param> | |
public SingleInstance(Guid id) | |
{ | |
this.identifier = id; | |
mutex = new Mutex(true, identifier.ToString(), out ownsMutex); | |
} | |
/// <summary> | |
/// Gets a value indicating whether this instance is first instance. | |
/// </summary> | |
/// <value> | |
/// <c>true</c> if this instance is first instance; otherwise, <c>false</c>. | |
/// </value> | |
public bool IsFirstInstance | |
{ | |
get | |
{ | |
return ownsMutex; | |
} | |
} | |
/// <summary> | |
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. | |
/// </summary> | |
public void Dispose() | |
{ | |
if (mutex != null && ownsMutex) | |
{ | |
mutex.ReleaseMutex(); | |
mutex = null; | |
} | |
} | |
/// <summary> | |
/// Passes the arguments to first instance. | |
/// </summary> | |
/// <param name="argument">The argument.</param> | |
public void PassArgumentsToFirstInstance(string argument) | |
{ | |
using (var client = new NamedPipeClientStream(identifier.ToString())) | |
using (var writer = new StreamWriter(client)) | |
{ | |
client.Connect(200); | |
writer.WriteLine(argument); | |
} | |
} | |
/// <summary> | |
/// Listens for arguments from successive instances. | |
/// </summary> | |
public void ListenForArgumentsFromSuccessiveInstances() | |
{ | |
Task.Factory.StartNew(() => | |
{ | |
using (var server = new NamedPipeServerStream(identifier.ToString())) | |
using (var reader = new StreamReader(server)) | |
{ | |
while (true) | |
{ | |
server.WaitForConnection(); | |
var argument = string.Empty; | |
while (server.IsConnected) | |
{ | |
argument += reader.ReadLine(); | |
} | |
CallOnArgumentsReceived(argument); | |
server.Disconnect(); | |
} | |
} | |
}); | |
} | |
/// <summary> | |
/// Calls the on arguments received. | |
/// </summary> | |
/// <param name="state">The state.</param> | |
public void CallOnArgumentsReceived(object state) | |
{ | |
if (ArgumentsReceived != null) | |
{ | |
if (state == null) | |
{ | |
state = string.Empty; | |
} | |
ArgumentsReceived(this, new GenericEventArgs<string>() { Data = state.ToString() }); | |
} | |
} | |
} | |
} |
Line 21 of ApplicatioStartup.cs should read
static void SingleInstanceParameter(object sender, GenericEventArgs<string> e)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note that the code uses the .Net 4 Tasks, this can be replaced with threads if you want to use it in .Net 3.5. This also only passes the first argument through but can be easily changed to pass multiple.