mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-22 04:34:59 +00:00
code_review: PR #1185
- make `SourceGit` running in singleton mode - `TrySendArgsToExistingInstance` should not be called before `BuildAvaloniaApp().StartWithClassicDesktopLifetime(args)` since we may want to launch `SourceGit` as a core editor. - avoid `preference.json` to be saved by multiple instances. - move IPC code to models. Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
parent
09c0edef8e
commit
7d20f97f4e
5 changed files with 133 additions and 153 deletions
97
src/Models/IpcChannel.cs
Normal file
97
src/Models/IpcChannel.cs
Normal file
|
@ -0,0 +1,97 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.Models
|
||||
{
|
||||
public class IpcChannel : IDisposable
|
||||
{
|
||||
public bool IsFirstInstance
|
||||
{
|
||||
get => _server != null;
|
||||
}
|
||||
|
||||
public event Action<string> MessageReceived;
|
||||
|
||||
public IpcChannel()
|
||||
{
|
||||
try
|
||||
{
|
||||
_server = new NamedPipeServerStream("SourceGitIPCChannel", PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly);
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
Task.Run(StartServer);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// IGNORE
|
||||
}
|
||||
}
|
||||
|
||||
public void SendToFirstInstance(string cmd)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var client = new NamedPipeClientStream(".", "SourceGitIPCChannel", PipeDirection.Out))
|
||||
{
|
||||
client.Connect(1000);
|
||||
if (client.IsConnected)
|
||||
{
|
||||
using (var writer = new StreamWriter(client))
|
||||
{
|
||||
writer.Write(Encoding.UTF8.GetBytes(cmd));
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// IGNORE
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_server?.Close();
|
||||
}
|
||||
|
||||
private async void StartServer()
|
||||
{
|
||||
var buffer = new byte[1024];
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _server.WaitForConnectionAsync(_cancellationTokenSource.Token);
|
||||
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var readed = await _server.ReadAsync(buffer.AsMemory(0, 1024), _cancellationTokenSource.Token);
|
||||
if (readed == 0)
|
||||
break;
|
||||
|
||||
stream.Write(buffer, 0, readed);
|
||||
}
|
||||
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
MessageReceived?.Invoke(Encoding.UTF8.GetString(stream.ToArray()).Trim());
|
||||
_server.Disconnect();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// IGNORE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private NamedPipeServerStream _server = null;
|
||||
private CancellationTokenSource _cancellationTokenSource = null;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue