Select Git revision
RunnableWrapper.cs

Benedikt Heinrichs authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
RunnableWrapper.cs 4.64 KiB
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Threading;
namespace Coscine.ServiceWrapper
{
class RunnableWrapper
{
private Process process;
private object __lockObj = new object();
// Thread safe singleton
private static RunnableWrapper instance = null;
private static readonly object padlock = new object();
private string executablePath = null;
public static RunnableWrapper Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new RunnableWrapper();
}
return instance;
}
}
}
private RunnableWrapper()
{
}
private void KillAllProcesses(string exectuablePath)
{
var wmiQueryString = "SELECT ProcessId, ExecutablePath, CommandLine FROM Win32_Process";
using (var searcher = new ManagementObjectSearcher(wmiQueryString))
using (var results = searcher.Get())
{
var query = from p in Process.GetProcesses()
join mo in results.Cast<ManagementObject>()
on p.Id equals (int)(uint)mo["ProcessId"]
select new
{
Process = p,
Path = (string)mo["ExecutablePath"],
CommandLine = (string)mo["CommandLine"],
};
foreach (var item in query)
{
if(item.Path == exectuablePath)
{
if (!item.Process.HasExited)
{
if (!item.Process.HasExited)
{
item.Process.Kill();
}
}
}
}
}
}
public void Start(string[] args, string executablePath)
{
try
{
this.executablePath = executablePath;
KillAllProcesses(executablePath);
if (process == null)
{
process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = executablePath;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.Arguments = string.Join(" ", args);
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
//* Set your output and error (asynchronous) handlers
process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
}
}
catch (Exception e)
{
File.AppendAllText(Path.GetTempPath() + "ServiceWrapper.log", $"{DateTime.Now}: {e.Message}{Environment.NewLine}");
}
}
private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
lock (__lockObj)
{
//* Do your stuff with the output (write to console/log/StringBuilder)
File.AppendAllText(Path.GetTempPath() + "ServiceWrapper.log", $"{DateTime.Now}: {outLine.Data}{Environment.NewLine}");
}
}
public void Stop()
{
try
{
if (process != null && !process.HasExited)
{
process.StandardInput.WriteLine("\x3");
Thread.Sleep(1000);
process.StandardInput.Close();
Thread.Sleep(1000);
if (!process.HasExited)
{
process.Kill();
}
KillAllProcesses(this.executablePath);
}
}
catch (Exception e)
{
File.AppendAllText(Path.GetTempPath() + "ServiceWrapper.log", $"{DateTime.Now}:{e.Message}{Environment.NewLine}");
}
}
}
}