Ultron.Ngrok/Ultron.Ngrok/FormMain.cs

363 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;
using System.Resources;
using System.Threading;
using System.Net;
using System.IO;
using Ultron.Ngrok.Utils;
using Ultron.Ngrok.Properties;
namespace Ultron.Ngrok
{
public partial class FormMain : Form
{
public delegate void CmdInitAlready();
#region
/// <summary>
/// 命令行
/// </summary>
public CmdUtils cmd { get; set; }
/// <summary>
/// 设置
/// </summary>
public SettingForm setting { get; set; }
/// <summary>
/// 数据集名称
/// </summary>
public string AssemblyProduct
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyProductAttribute)attributes[0]).Product;
}
}
/// <summary>
/// 数据集版本
/// </summary>
public string AssemblyVersion
{
get
{
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
}
#endregion
#region
/// <summary>
/// 构造
/// </summary>
public FormMain()
{
//引用资源处理
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
//初始化界面
InitializeComponent();
//初始化配置
InitSetting();
}
/// <summary>
/// 窗体Load
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormMain_Load(object sender, EventArgs e)
{
//进程检测
CheckProcessAndKill(setting.ExeFile);
CmdInitAlready callback = new CmdInitAlready(CmdCallBack);
//初始化CMD
Thread cmdThread = new Thread(InitCmd);
cmdThread.IsBackground = true;
cmdThread.Start(callback);
//检查更新
Thread updateThread = new Thread(new ThreadStart(CheckUpdateAsync));
updateThread.IsBackground = true;
updateThread.Start();
}
public void CmdCallBack()
{
if(setting.ServerConfig.AutoStart)
{
startBtn_Click(null, null);
}
}
#endregion
#region
private void startBtn_Click(object sender, EventArgs e)
{
//网络检测
NetworkUtils.CheckServeStatus(this);
cmd.SendMsg(setting.ExecuteCommand,setting.ServerConfig.HideWindow);
startBtn.Enabled = false;
endBtn.Enabled = true;
}
private void endBtn_Click(object sender, EventArgs e)
{
CheckProcessAndKill(setting.ExeFile);
cmd.CloseCmd();
startBtn.Enabled = true;
endBtn.Enabled = false;
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
setting.ReLoadConfig();
setting.ShowDialog();
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
Process.Start("explorer.exe", "https://git.wixy.cn/wixy/Ultron.Ngrok/wiki/帮助");
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutBox about = new AboutBox();
about.ShowDialog();
}
private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
this.WindowState = FormWindowState.Normal;
if (this.Visible == false)
this.Show();
}
private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
{
if (setting.ServerConfig.UseNotifyMenu)
{
notifyIcon.Visible = true;
this.Hide();
e.Cancel = true;
}
else
{
if (MessageBox.Show("是否确认退出程序?", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
{
// 关闭所有的线程
this.Dispose();
this.Close();
}
else
{
e.Cancel = true;
}
}
}
private void 退ToolStripMenuItem_Click(object sender, EventArgs e)
{
if (MessageBox.Show("是否确认退出程序?", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
{
this.Dispose();
this.Close();
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
WindowState = FormWindowState.Normal;
}
#endregion
#region
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", "");
dllName = dllName.Replace(".", "_");
if (dllName.EndsWith("_resources")) return null;
ResourceManager rm = new ResourceManager(GetType().Namespace + ".Properties.Resources", Assembly.GetExecutingAssembly());
byte[] bytes = (byte[])rm.GetObject(dllName);
return Assembly.Load(bytes);
}
public void CheckProcessAndKill(string processName)
{
Process[] proces = Process.GetProcessesByName(processName);
foreach (var item in proces)
{
WriteLog("检测到进程:" + item.ProcessName + "ID" + item.Id + "");
item.Kill();
WriteLog("结束进程:" + item.Id + "");
}
}
public void CheckProcessAndKill(int id)
{
Process proces = Process.GetProcessById(id);
if (proces != null)
{
WriteLog("检测到进程:" + proces.ProcessName + "ID" + proces.Id + "");
proces.Kill();
WriteLog("结束进程:" + proces.Id + "");
}
}
public void InitSetting()
{
setting = new SettingForm();
setting.WriteLogToForm += WriteLog;
}
public void InitCmd(object obj)
{
//创建CMD
cmd = new CmdUtils();
cmd.ProcessMessageEvent += DealMessage;
cmd.ProcessKilled += cmd_Exited;
CmdInitAlready callback = obj as CmdInitAlready;
callback();
}
/// <summary>
/// 检查更新
/// </summary>
public void CheckUpdateAsync()
{
string checkUrl = "https://blog.wixy.cn/api/release/" + AssemblyProduct + "/" + AssemblyVersion;
HttpGet(checkUrl);
}
public void DealMessage(int proId, string message)
{
if (message.StartsWith("Server failed to allocate tunnel"))
{
if (message.Contains("address already in use"))
{
string tcpErr = message.Substring(message.IndexOf("listen tcp"));
WriteLog(tcpErr);
int domainIndex = message.IndexOf("0.0.0.0:") + 8;
int portIndex = message.IndexOf(": bind:");
string port = message.Substring(domainIndex, portIndex - domainIndex);
MessageBox.Show("通道分配失败,端口:" + port + "已被使用!");
}
else if (message.Contains("is already registered"))
{
string tcpErr = message.Substring(message.IndexOf("The tunnel "));
WriteLog(tcpErr);
int domainIndex = message.IndexOf("http://");
int strIndex = message.IndexOf("is already");
string domain = message.Substring(domainIndex, strIndex - domainIndex);
MessageBox.Show("通道分配失败,域名:" + domain + "已被使用!");
}
CheckProcessAndKill(proId);
startBtn.Enabled = true;
endBtn.Enabled = false;
}
else
{
if (message.Contains("Microsoft Windows") || message.Contains("Microsoft Corporation") || message.Contains(".exe -config ngrok.cfg start"))
return;
WriteLog(message);
}
}
public void WriteLog(string message)
{
StringBuilder sb = new StringBuilder(cmdLogTextArea.Text);
cmdLogTextArea.Text = sb.AppendLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss ") + message).ToString();
cmdLogTextArea.SelectionStart = cmdLogTextArea.Text.Length;
cmdLogTextArea.ScrollToCaret();
}
public void cmd_Exited(object sender, EventArgs e)
{
WriteLog("结束运行!");
startBtn.Enabled = true;
endBtn.Enabled = false;
}
public void HttpGet(string url)
{
string updateExe = Directory.GetCurrentDirectory() + @"\autoUpdate.exe";
if (File.Exists(updateExe))
{
File.Delete(updateExe);
}
FileStream stream = new FileStream(updateExe, FileMode.OpenOrCreate);
stream.Write(Resources.autoUpdate, 0, Resources.autoUpdate.Length);
stream.Close();
WebClient wc = new WebClient();
Uri uri = new Uri(url, UriKind.RelativeOrAbsolute);
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(uri);
}
public void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
StreamReader read = new StreamReader(e.Result);
string str = read.ReadToEnd();
if (str.Contains("\"code\":1"))
return;
else
{
if (MessageBox.Show("检测到新版本,立即更新?", "版本更新", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
int verStart = str.IndexOf("\"version\":\"") + 11;
int verEnd = str.IndexOf("\",\"title\"");
string version = str.Substring(verStart, verEnd - verStart);
RunUpdateProgram(version);
}
}
}
catch(Exception ex)
{
string msg = ex.InnerException == null ? ex.Message : ex.InnerException.Message;
MessageBox.Show($"无法检测更新:{msg}");
}
}
public void RunUpdateProgram(string verion)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "autoUpdate.exe";
startInfo.Arguments = "\"https://cloud-disk-1251608065.cos.ap-guangzhou.myqcloud.com/uNgrok_" + verion + ".exe" + " uNgrok.exe\"";
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.UseShellExecute = false;
Process.Start(startInfo);
Environment.Exit(0);
}
#endregion
}
}