mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-06-22 10:55:00 +00:00
feat: add safe command termination
This commit is contained in:
parent
b2ab62825e
commit
34ae392251
5 changed files with 115 additions and 13 deletions
|
@ -37,6 +37,12 @@ namespace SourceGit.Commands
|
|||
public string Args { get; set; } = string.Empty;
|
||||
public bool RaiseError { get; set; } = true;
|
||||
public bool TraitErrorAsOutput { get; set; } = false;
|
||||
public bool Cancelable { get; } = false;
|
||||
|
||||
public Command(bool cancelable = false)
|
||||
{
|
||||
Cancelable = cancelable;
|
||||
}
|
||||
|
||||
public bool Exec()
|
||||
{
|
||||
|
@ -109,12 +115,22 @@ namespace SourceGit.Commands
|
|||
return false;
|
||||
}
|
||||
|
||||
_proc = proc;
|
||||
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
proc.BeginOutputReadLine();
|
||||
proc.BeginErrorReadLine();
|
||||
proc.WaitForExit();
|
||||
|
||||
int exitCode = proc.ExitCode;
|
||||
exitCode = proc.ExitCode;
|
||||
proc.Close();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_proc = null;
|
||||
}
|
||||
|
||||
if (!isCancelled && exitCode != 0)
|
||||
{
|
||||
|
@ -150,6 +166,10 @@ namespace SourceGit.Commands
|
|||
};
|
||||
}
|
||||
|
||||
_proc = proc;
|
||||
|
||||
try
|
||||
{
|
||||
var rs = new ReadToEndResult()
|
||||
{
|
||||
StdOut = proc.StandardOutput.ReadToEnd(),
|
||||
|
@ -162,6 +182,22 @@ namespace SourceGit.Commands
|
|||
|
||||
return rs;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_proc = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void TryCancel()
|
||||
{
|
||||
if (!this.Cancelable)
|
||||
throw new Exception("Command is not cancelable!");
|
||||
|
||||
if (_proc is null)
|
||||
return;
|
||||
|
||||
Native.OS.TerminateSafely(_proc);
|
||||
}
|
||||
|
||||
protected virtual void OnReadline(string line)
|
||||
{
|
||||
|
@ -226,5 +262,7 @@ namespace SourceGit.Commands
|
|||
|
||||
[GeneratedRegex(@"\d+%")]
|
||||
private static partial Regex REG_PROGRESS();
|
||||
|
||||
private Process _proc = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
using Avalonia;
|
||||
|
@ -11,6 +12,14 @@ namespace SourceGit.Native
|
|||
[SupportedOSPlatform("linux")]
|
||||
internal class Linux : OS.IBackend
|
||||
{
|
||||
private enum SIGNAL : int
|
||||
{
|
||||
TERM = 15
|
||||
}
|
||||
|
||||
[DllImport("c")]
|
||||
private static extern int kill(int pid, int sig);
|
||||
|
||||
public void SetupApp(AppBuilder builder)
|
||||
{
|
||||
builder.With(new X11PlatformOptions() { EnableIme = true });
|
||||
|
@ -97,6 +106,12 @@ namespace SourceGit.Native
|
|||
}
|
||||
}
|
||||
|
||||
public void TerminateSafely(Process process)
|
||||
{
|
||||
if (kill(process.Id, (int)SIGNAL.TERM) == 0)
|
||||
process.WaitForExit();
|
||||
}
|
||||
|
||||
private string FindExecutable(string filename)
|
||||
{
|
||||
var pathVariable = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
using Avalonia;
|
||||
|
@ -11,6 +12,14 @@ namespace SourceGit.Native
|
|||
[SupportedOSPlatform("macOS")]
|
||||
internal class MacOS : OS.IBackend
|
||||
{
|
||||
private enum SIGNAL : int
|
||||
{
|
||||
TERM = 15
|
||||
}
|
||||
|
||||
[DllImport("System")]
|
||||
private static extern int kill(int pid, int sig);
|
||||
|
||||
public void SetupApp(AppBuilder builder)
|
||||
{
|
||||
builder.With(new MacOSPlatformOptions()
|
||||
|
@ -88,5 +97,11 @@ namespace SourceGit.Native
|
|||
{
|
||||
Process.Start("open", $"\"{file}\"");
|
||||
}
|
||||
|
||||
public void TerminateSafely(Process process)
|
||||
{
|
||||
if (kill(process.Id, (int)SIGNAL.TERM) == 0)
|
||||
process.WaitForExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ namespace SourceGit.Native
|
|||
void OpenInFileManager(string path, bool select);
|
||||
void OpenBrowser(string url);
|
||||
void OpenWithDefaultEditor(string file);
|
||||
|
||||
void TerminateSafely(Process process);
|
||||
}
|
||||
|
||||
public static string DataDir
|
||||
|
@ -168,6 +170,11 @@ namespace SourceGit.Native
|
|||
_backend.OpenWithDefaultEditor(file);
|
||||
}
|
||||
|
||||
public static void TerminateSafely(Process process)
|
||||
{
|
||||
_backend.TerminateSafely(process);
|
||||
}
|
||||
|
||||
private static void UpdateGitVersion()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_gitExecutable) || !File.Exists(_gitExecutable))
|
||||
|
|
|
@ -35,6 +35,11 @@ namespace SourceGit.Native
|
|||
public int cyBottomHeight;
|
||||
}
|
||||
|
||||
private enum CTRL_EVENT : int
|
||||
{
|
||||
CTRL_C = 0
|
||||
}
|
||||
|
||||
[DllImport("ntdll.dll")]
|
||||
private static extern int RtlGetVersion(ref RTL_OSVERSIONINFOEX lpVersionInformation);
|
||||
|
||||
|
@ -53,6 +58,12 @@ namespace SourceGit.Native
|
|||
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = false)]
|
||||
private static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, int cild, IntPtr apidl, int dwFlags);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool SetConsoleCtrlHandler(IntPtr handlerRoutine, bool add);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool GenerateConsoleCtrlEvent(int dwCtrlEvent, int dwProcessGroupId);
|
||||
|
||||
public void SetupApp(AppBuilder builder)
|
||||
{
|
||||
// Fix drop shadow issue on Windows 10
|
||||
|
@ -212,6 +223,22 @@ namespace SourceGit.Native
|
|||
Process.Start(start);
|
||||
}
|
||||
|
||||
public void TerminateSafely(Process process)
|
||||
{
|
||||
if (SetConsoleCtrlHandler(IntPtr.Zero, true))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (GenerateConsoleCtrlEvent((int)CTRL_EVENT.CTRL_C, process.Id))
|
||||
process.WaitForExit();
|
||||
}
|
||||
finally
|
||||
{
|
||||
SetConsoleCtrlHandler(IntPtr.Zero, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FixWindowFrameOnWin10(Window w)
|
||||
{
|
||||
var platformHandle = w.TryGetPlatformHandle();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue