Handler
V2rayHandler.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using v2rayN.Mode;
namespace v2rayN.Handler
{
///
/// 消息委托
///
/// 是否显示在托盘区
/// 内容
public delegate void ProcessDelegate(bool notify, string msg);
///
/// v2ray进程处理类
///
clast V2rayHandler
{
private static string v2rayConfigRes = Global.v2rayConfigFileName;
private List lstV2ray;
private string coreUrl;
public event ProcessDelegate ProcessEvent;
//private int processId = 0;
private Process _process;
public V2rayHandler()
{
}
///
/// 载入V2ray
///
public void LoadV2ray(Config config)
{
if (config.coreType == ECoreType.v2fly_core)
{
lstV2ray = new List
{
"wv2ray",
"v2ray"
};
coreUrl = Global.v2flyCoreUrl;
}
else
{
lstV2ray = new List
{
"xray"
};
coreUrl = Global.xrayCoreUrl;
}
if (Global.reloadV2ray)
{
string fileName = Utils.GetPath(v2rayConfigRes);
if (V2rayConfigHandler.GenerateClientConfig(config, fileName, false, out string msg) != 0)
{
ShowMsg(false, msg);
}
else
{
ShowMsg(true, msg);
V2rayRestart();
}
}
}
///
/// 新建进程,载入V2ray配置文件字符串
/// 返回新进程pid。
///
public int LoadV2rayConfigString(Config config, List _selecteds)
{
int pid = -1;
string configStr = V2rayConfigHandler.GenerateClientSpeedtestConfigString(config, _selecteds, out string msg);
if (configStr == "")
{
ShowMsg(false, msg);
}
else
{
ShowMsg(false, msg);
pid = V2rayStartNew(configStr);
//V2rayRestart();
// start with -config
}
return pid;
}
///
/// V2ray重启
///
private void V2rayRestart()
{
V2rayStop();
V2rayStart();
}
///
/// V2ray停止
///
public void V2rayStop()
{
try
{
if (_process != null)
{
KillProcess(_process);
_process.Dispose();
_process = null;
}
else
{
foreach (string vName in lstV2ray)
{
Process[] existing = Process.GetProcessesByName(vName);
foreach (Process p in existing)
{
string path = p.MainModule.FileName;
if (path == $"{Utils.GetPath(vName)}.exe")
{
KillProcess(p);
}
}
}
}
//bool blExist = true;
//if (processId > 0)
//{
// Process p1 = Process.GetProcessById(processId);
// if (p1 != null)
// {
// p1.Kill();
// blExist = false;
// }
//}
//if (blExist)
//{
// foreach (string vName in lstV2ray)
// {
// Process[] killPro = Process.GetProcessesByName(vName);
// foreach (Process p in killPro)
// {
// p.Kill();
// }
// }
//}
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
}
}
///
/// V2ray停止
///
public void V2rayStopPid(int pid)
{
try
{
Process _p = Process.GetProcessById(pid);
KillProcess(_p);
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
}
}
private string V2rayFindexe()
{
//查找v2ray文件是否存在
string fileName = string.Empty;
//lstV2ray.Reverse();
foreach (string name in lstV2ray)
{
string vName = string.Format("{0}.exe", name);
vName = Utils.GetPath(vName);
if (File.Exists(vName))
{
fileName = vName;
break;
}
}
if (Utils.IsNullOrEmpty(fileName))
{
string msg = string.Format(UIRes.I18N("NotFoundCore"), coreUrl);
ShowMsg(false, msg);
}
return fileName;
}
///
/// V2ray启动
///
private void V2rayStart()
{
ShowMsg(false, string.Format(UIRes.I18N("StartService"), DateTime.Now.ToString()));
try
{
string fileName = V2rayFindexe();
if (fileName == "") return;
Process p = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = fileName,
WorkingDirectory = Utils.StartupPath(),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
StandardOutputEncoding = Encoding.UTF8
}
};
p.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
string msg = e.Data + Environment.NewLine;
ShowMsg(false, msg);
}
});
p.Start();
p.PriorityClast = ProcessPriorityClast.High;
p.BeginOutputReadLine();
//processId = p.Id;
_process = p;
if (p.WaitForExit(1000))
{
throw new Exception(p.StandardError.ReadToEnd());
}
Global.processJob.AddProcess(p.Handle);
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
string msg = ex.Message;
ShowMsg(true, msg);
}
}
///
/// V2ray启动,新建进程,传入配置字符串
///
private int V2rayStartNew(string configStr)
{
ShowMsg(false, string.Format(UIRes.I18N("StartService"), DateTime.Now.ToString()));
try
{
string fileName = V2rayFindexe();
if (fileName == "") return -1;
Process p = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = fileName,
Arguments = "-config stdin:",
WorkingDirectory = Utils.StartupPath(),
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
StandardOutputEncoding = Encoding.UTF8
}
};
p.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
string msg = e.Data + Environment.NewLine;
ShowMsg(false, msg);
}
});
p.Start();
p.BeginOutputReadLine();
p.StandardInput.Write(configStr);
p.StandardInput.Close();
if (p.WaitForExit(1000))
{
throw new Exception(p.StandardError.ReadToEnd());
}
Global.processJob.AddProcess(p.Handle);
return p.Id;
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
string msg = ex.Message;
ShowMsg(false, msg);
return -1;
}
}
///
/// 消息委托
///
/// 是否更新托盘图标的工具提示
/// 输出到日志框
private void ShowMsg(bool updateToTrayTooltip, string msg)
{
ProcessEvent?.Invoke(updateToTrayTooltip, msg);
}
private void KillProcess(Process p)
{
try
{
p.CloseMainWindow();
p.WaitForExit(100);
if (!p.HasExited)
{
p.Kill();
p.WaitForExit(100);
}
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
}
}
}
}