mirror of
https://github.com/ckaczor/ChrisKaczor.Wpf.Application.SingleInstance.git
synced 2026-01-13 17:22:25 -05:00
Initial commit
This commit is contained in:
15
README.md
Normal file
15
README.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# ChrisKaczor.Wpf.Application.SingleInstance
|
||||||
|
|
||||||
|
This library can be used to restrict an application to only a single instance and sends the command line of any newly started instance to the currently running instance.
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
|
* **Chris Kaczor** - *Initial work* - https://github.com/ckaczor - https://chriskaczor.com
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
This code is used by my various personal projects and may not be useful or work in all use cases.
|
||||||
67
SingleInstance.cs
Normal file
67
SingleInstance.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using H.Pipes;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ChrisKaczor.Wpf.Application
|
||||||
|
{
|
||||||
|
public static class SingleInstance
|
||||||
|
{
|
||||||
|
public static event EventHandler<string> MessageReceived = delegate { };
|
||||||
|
|
||||||
|
private static PipeServer<string>? _pipeServer;
|
||||||
|
private static SynchronizationContext? _syncContext;
|
||||||
|
|
||||||
|
public static async Task<IDisposable?> GetSingleInstanceHandleAsync(string applicationName)
|
||||||
|
{
|
||||||
|
// Create the mutex and see if it was newly created
|
||||||
|
var mutex = new Mutex(false, applicationName, out var createdNew);
|
||||||
|
|
||||||
|
// Return the mutex if it was created
|
||||||
|
if (createdNew) return mutex;
|
||||||
|
|
||||||
|
// Create a client to send to the other instance
|
||||||
|
await using var pipeClient = new PipeClient<string>(applicationName);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Connect to the other instance
|
||||||
|
await pipeClient.ConnectAsync(new CancellationTokenSource(500).Token);
|
||||||
|
|
||||||
|
// Send the command line to the other instance
|
||||||
|
await pipeClient.WriteAsync(Environment.CommandLine);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task StartAsync(string applicationName)
|
||||||
|
{
|
||||||
|
// Store the synchronization context of the current thread
|
||||||
|
_syncContext = SynchronizationContext.Current;
|
||||||
|
|
||||||
|
_pipeServer = new PipeServer<string>(applicationName);
|
||||||
|
|
||||||
|
_pipeServer.MessageReceived += PipeServer_MessageReceived;
|
||||||
|
|
||||||
|
await _pipeServer.StartAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task Stop()
|
||||||
|
{
|
||||||
|
if (_pipeServer == null) return;
|
||||||
|
|
||||||
|
await _pipeServer.StopAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PipeServer_MessageReceived(object? sender, H.Pipes.Args.ConnectionMessageEventArgs<string?> e)
|
||||||
|
{
|
||||||
|
// Fire the event on the original thread
|
||||||
|
_syncContext?.Send(_ => MessageReceived(null, e.Message!), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Wpf.Application.SingleInstance.csproj
Normal file
13
Wpf.Application.SingleInstance.csproj
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0-windows</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<UseWPF>true</UseWPF>
|
||||||
|
<RootNamespace>ChrisKaczor.Wpf.Application</RootNamespace>
|
||||||
|
<Title>ChrisKaczor.Wpf.Application.SingleInstance</Title>
|
||||||
|
<Authors>Chris Kaczor</Authors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="H.Pipes" Version="2.0.47" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
25
Wpf.Application.SingleInstance.sln
Normal file
25
Wpf.Application.SingleInstance.sln
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.5.33516.290
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Application.SingleInstance", "Wpf.Application.SingleInstance.csproj", "{6A5FBB13-4B83-4F7D-84CC-9474711100EA}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{6A5FBB13-4B83-4F7D-84CC-9474711100EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6A5FBB13-4B83-4F7D-84CC-9474711100EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6A5FBB13-4B83-4F7D-84CC-9474711100EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6A5FBB13-4B83-4F7D-84CC-9474711100EA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {9AF9F429-2093-4B89-96EB-C55EFBFD6EDD}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
Reference in New Issue
Block a user