Skip to content

Commit 1dc9f29

Browse files
committed
Added ObsoleteSingleInstance to prevent breaking projects
1 parent 1189579 commit 1dc9f29

File tree

3 files changed

+94
-1
lines changed

3 files changed

+94
-1
lines changed

src/ObsoleteSingleInstance.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Text;
5+
using System.Threading;
6+
using System.Windows;
7+
using TinyIpc.Messaging;
8+
9+
namespace SingleInstanceCore
10+
{
11+
[Obsolete("Use non-generic SingleInstance class instead. Check updated example on Github https://github.com/soheilkd/SingleInstanceCore")]
12+
public static class SingleInstance<TApplication>
13+
where TApplication : Application, ISingleInstance
14+
{
15+
private const string channelNameSufflix = ":SingeInstanceIPCChannel";
16+
private static Mutex singleMutex;
17+
private static TinyMessageBus messageBus; //IPC message bus for communication between instances
18+
19+
/// <summary>
20+
/// Intended to be on app startup
21+
/// Initializes service if the call is from first instance
22+
/// Signals the first instance if it already exists
23+
/// </summary>
24+
/// <param name="uniqueName">A unique name for IPC channel</param>
25+
/// <returns>Whether the call is from application's first instance</returns>
26+
public static bool InitializeAsFirstInstance(string uniqueName)
27+
{
28+
var CommandLineArgs = GetCommandLineArgs(uniqueName);
29+
var applicationIdentifier = uniqueName + Environment.UserName;
30+
var channelName = $"{applicationIdentifier}{channelNameSufflix}";
31+
singleMutex = new Mutex(true, applicationIdentifier, out var firstInstance);
32+
33+
if (firstInstance)
34+
CreateRemoteService(channelName);
35+
else
36+
SignalFirstInstance(channelName, CommandLineArgs);
37+
38+
return firstInstance;
39+
}
40+
41+
private static void SignalFirstInstance(string channelName, IList<string> commandLineArgs) => new TinyMessageBus(channelName).PublishAsync(commandLineArgs.Serialize());
42+
43+
private static void CreateRemoteService(string channelName)
44+
{
45+
messageBus = new TinyMessageBus(channelName);
46+
messageBus.MessageReceived += MessageBus_MessageReceived;
47+
}
48+
49+
private static void MessageBus_MessageReceived(object sender, TinyMessageReceivedEventArgs e)
50+
{
51+
var app = Application.Current as TApplication;
52+
var args = e.Message.Deserialize<string[]>();
53+
app.OnInstanceInvoked(args);
54+
}
55+
56+
private static string[] GetCommandLineArgs(string uniqueApplicationName)
57+
{
58+
var args = Environment.GetCommandLineArgs();
59+
if (args == null)
60+
{
61+
// Try getting commandline arguments from shared location in case of ClickOnce deployed application
62+
var appFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), uniqueApplicationName);
63+
var cmdLinePath = Path.Combine(appFolderPath, "cmdline.txt");
64+
if (File.Exists(cmdLinePath))
65+
{
66+
try
67+
{
68+
using var reader = new StreamReader(cmdLinePath, Encoding.Unicode);
69+
args = NativeMethods.CommandLineToArgvW(reader.ReadToEnd());
70+
File.Delete(cmdLinePath);
71+
}
72+
catch (IOException) { }
73+
}
74+
}
75+
return args ?? Array.Empty<string>();
76+
}
77+
78+
public static void Cleanup()
79+
{
80+
if (messageBus != null)
81+
{
82+
messageBus.Dispose();
83+
messageBus = null;
84+
}
85+
if (singleMutex != null)
86+
{
87+
singleMutex.Close();
88+
singleMutex = null;
89+
}
90+
}
91+
}
92+
}

src/SingleInstanceCore.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<useWPF>true</useWPF>
56
<Authors>soheilkd</Authors>
67
<Company />
78
<PackageProjectUrl>https://github.com/soheilkd/SingleInstanceCore</PackageProjectUrl>

src/SingleInstanceCore.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 16
44
VisualStudioVersion = 16.0.29806.167
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SingleInstanceCore", "SingleInstanceCore.csproj", "{215AAC6C-2C2D-4A1C-B8A3-A68545A00983}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SingleInstanceCore", "SingleInstanceCore.csproj", "{215AAC6C-2C2D-4A1C-B8A3-A68545A00983}"
77
EndProject
88
Global
99
GlobalSection(SolutionConfigurationPlatforms) = preSolution

0 commit comments

Comments
 (0)