-
Notifications
You must be signed in to change notification settings - Fork 385
Expand file tree
/
Copy pathIpcChannel.cs
More file actions
100 lines (88 loc) · 3.12 KB
/
IpcChannel.cs
File metadata and controls
100 lines (88 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using System;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Threading.Tasks;
namespace SourceGit.Models
{
public class IpcChannel : IDisposable
{
public bool IsFirstInstance { get; }
public event Action<string> MessageReceived;
public IpcChannel()
{
try
{
_singletonLock = File.Open(Path.Combine(Native.OS.DataDir, "process.lock"), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
IsFirstInstance = true;
_server = new NamedPipeServerStream(
"SourceGitIPCChannel" + Environment.UserName,
PipeDirection.In,
-1,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly);
_cancellationTokenSource = new CancellationTokenSource();
Task.Run(StartServer);
}
catch
{
IsFirstInstance = false;
}
}
public void SendToFirstInstance(string cmd)
{
try
{
using (var client = new NamedPipeClientStream(".", "SourceGitIPCChannel" + Environment.UserName, PipeDirection.Out, PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly))
{
client.Connect(1000);
if (!client.IsConnected)
return;
using (var writer = new StreamWriter(client))
{
writer.WriteLine(cmd);
writer.Flush();
}
if (OperatingSystem.IsWindows())
client.WaitForPipeDrain();
else
Thread.Sleep(1000);
}
}
catch
{
// IGNORE
}
}
public void Dispose()
{
_cancellationTokenSource?.Cancel();
_singletonLock?.Dispose();
}
private async void StartServer()
{
using var reader = new StreamReader(_server);
while (!_cancellationTokenSource.IsCancellationRequested)
{
try
{
await _server.WaitForConnectionAsync(_cancellationTokenSource.Token);
if (!_cancellationTokenSource.IsCancellationRequested)
{
var line = await reader.ReadToEndAsync(_cancellationTokenSource.Token);
MessageReceived?.Invoke(line.Trim());
}
_server.Disconnect();
}
catch
{
if (!_cancellationTokenSource.IsCancellationRequested && _server.IsConnected)
_server.Disconnect();
}
}
}
private FileStream _singletonLock = null;
private NamedPipeServerStream _server = null;
private CancellationTokenSource _cancellationTokenSource = null;
}
}