using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Windows.Forms; using Ultron.Ngrok.Model; using Ultron.Ngrok.Properties; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; namespace Ultron.Ngrok { public partial class SettingForm : Form { public delegate void WriteLog(string message); public event WriteLog WriteLogToForm; /// /// 配置 /// public Config ServerConfig { get; set; } /// /// 配置文件 /// public string ConfigFile { get; set; } /// /// 执行命令 /// public string ExecuteCommand { get; set; } /// /// 执行文件名 /// public string ExeFile { get; set; } public SettingForm() { InitializeComponent(); InitFile(); InitConfig(); LoadConfig(); } public void InitFile() { string path = Directory.GetCurrentDirectory(); string ngrokFile = string.Empty; if (Environment.Is64BitOperatingSystem)//判断是否为64位操作系统 { ngrokFile = path + @"\ngrok_x64.exe"; if (!File.Exists(ngrokFile)) { FileStream str = new FileStream(ngrokFile, FileMode.OpenOrCreate); str.Write(Resources.ngrok_x64, 0, Resources.ngrok_x64.Length); str.Close(); } ExeFile = "ngrok_x64"; } else { ngrokFile = path + @"\ngrok_x86.exe"; if (!File.Exists(ngrokFile)) { FileStream str = new FileStream(ngrokFile, FileMode.OpenOrCreate); str.Write(Resources.ngrok_x86, 0, Resources.ngrok_x86.Length); str.Close(); } ExeFile = "ngrok_x86"; } } public string AssemblyVersion { get { return Assembly.GetExecutingAssembly().GetName().Version.ToString(); } } /// /// 初始化配置文件 /// public void InitConfig() { string path = Directory.GetCurrentDirectory(); ConfigFile = path + @"\ngrok.cfg"; if (!File.Exists(ConfigFile)) { FileStream fs1 = new FileStream(ConfigFile, FileMode.Create, FileAccess.Write);//创建写入文件 StreamWriter sw = new StreamWriter(fs1); ServerConfig = new Config { ServerAddr = "ngrok.aaqbee.com:8083", TrustHostRootCerts = false, Version = AssemblyVersion, Tunnels = new Dictionary() }; Tunnel httpTunnel = new Tunnel { SubDomain = "test", TunnelName = "test", Proto = new Dictionary(), Enable = true, TunnelID = Guid.NewGuid().ToString() }; httpTunnel.Proto.Add("http", "127.0.0.1:5000"); ServerConfig.Tunnels.Add(httpTunnel.TunnelID, httpTunnel); Tunnel tcpTunnel = new Tunnel { TunnelName = "mstsc", RemotePort = 33099, Proto = new Dictionary(), Enable = true, TunnelID = Guid.NewGuid().ToString() }; tcpTunnel.Proto.Add("tcp", "127.0.0.1:1433"); ServerConfig.Tunnels.Add(tcpTunnel.TunnelID, tcpTunnel); var serializer = new Serializer(); serializer.Serialize(sw, ServerConfig); sw.Close(); fs1.Close(); } else { string configText = File.ReadAllText(ConfigFile, Encoding.UTF8); var input = new StringReader(configText); var deserializer = new Deserializer(namingConvention: new CamelCaseNamingConvention()); ServerConfig = deserializer.Deserialize(input); if(ServerConfig.Version != AssemblyVersion) { ServerConfig.Version = AssemblyVersion; SaveConfig(); } } this.tunnelListBox.DisplayMember = "TunnelName"; this.tunnelListBox.ValueMember = "TunnelID"; } /// /// 加载配置文件 /// public void LoadConfig() { tunnelListBox.Items.Clear(); foreach(var item in ServerConfig.Tunnels) { tunnelListBox.Items.Add(item.Value); } if (tunnelListBox.Items.Count>0) tunnelListBox.SelectedIndex = 0; string tunnelName = string.Empty; foreach (var item in ServerConfig.Tunnels.Where(p => p.Value.Enable)) { tunnelName += " " + item.Key; } ExecuteCommand = ExeFile + ".exe -config ngrok.cfg start" + tunnelName; } public void ReLoadConfig() { string configText = File.ReadAllText(ConfigFile, Encoding.UTF8); var input = new StringReader(configText); var deserializer = new Deserializer(namingConvention: new CamelCaseNamingConvention()); ServerConfig = deserializer.Deserialize(input); LoadConfig(); } /// /// 通道类型选择 /// /// /// private void tunnelTypeCMB_SelectedIndexChanged(object sender, EventArgs e) { ComboBox cmb = sender as ComboBox; if (cmb.SelectedItem.ToString() == "HTTP") { subdomainLBL.Visible = true; tunnelTypeLabelPort.Visible = false; subdomainTB.KeyPress -= subdomainTB_KeyPress; } else { tunnelTypeLabelPort.Visible = true; subdomainLBL.Visible = false; subdomainTB.KeyPress += subdomainTB_KeyPress; } } /// /// 子域名框按键释放 /// /// /// void subdomainTB_KeyPress(object sender, KeyPressEventArgs e) { //阻止从键盘输入键 e.Handled = true; if((e.KeyChar>='0' && e.KeyChar <='9') || e.KeyChar == '\b') e.Handled = false; } /// /// 切换通道 /// /// /// private void tunnelListBox_SelectedValueChanged(object sender, EventArgs e) { ListBox lbx = sender as ListBox; if(lbx != null && lbx.SelectedItem != null) { Tunnel tunl = lbx.SelectedItem as Tunnel; tunnelNameTB.Text = tunl.TunnelName; tunnelTypeCMB.Text = tunl.Proto.ContainsKey("http") ? "HTTP" : "TCP"; if (tunnelTypeCMB.Text == "HTTP") { subdomainLBL.Visible = true; tunnelTypeLabelPort.Visible = false; subdomainTB.Text = tunl.SubDomain; } else { tunnelTypeLabelPort.Visible = true; subdomainLBL.Visible = false; subdomainTB.Text = tunl.RemotePort.ToString(); } string ipPort = tunl.Proto.FirstOrDefault().Value; ipTB.Text = ipPort.Substring(0, ipPort.IndexOf(":")); portTB.Text = ipPort.Substring(ipPort.IndexOf(":")+1); enableCBX.Checked = tunl.Enable; } } /// /// 删除 /// /// /// private void delButton_Click(object sender, EventArgs e) { ListBox lbx = tunnelListBox as ListBox; if (lbx != null && lbx.SelectedItem != null) { Tunnel tunl = lbx.SelectedItem as Tunnel; ServerConfig.Tunnels.Remove(tunl.TunnelID); //SaveConfig(); } LoadConfig(); } /// /// 新增 /// /// /// private void addButton_Click(object sender, EventArgs e) { Tunnel tunl = new Tunnel { RemotePort = 33000, Proto = new Dictionary(), Enable = true, TunnelID = Guid.NewGuid().ToString(), TunnelName = "新增通道" }; tunl.Proto.Add("tcp", "127.0.0.1:80"); ServerConfig.Tunnels.Add(tunl.TunnelID, tunl); LoadConfig(); tunnelListBox.SelectedItem = tunl; } /// /// 保存 /// /// /// private void saveButton_Click(object sender, EventArgs e) { if (tunnelListBox != null && tunnelListBox.SelectedItem != null) { Tunnel tunl = tunnelListBox.SelectedItem as Tunnel; if (tunnelTypeCMB.Text == "HTTP") { tunl.Proto.Clear(); tunl.Proto.Add("http", ipTB.Text + ":" + portTB.Text); tunl.SubDomain = subdomainTB.Text; } else { tunl.Proto.Clear(); tunl.Proto.Add("tcp", ipTB.Text + ":" + portTB.Text); tunl.RemotePort = Int32.Parse(subdomainTB.Text); } tunl.TunnelName = tunnelNameTB.Text; tunl.Enable = enableCBX.Checked; SaveConfig(); LoadConfig(); } WriteLogToForm("保存成功"); this.Close(); } public void SaveConfig() { FileStream fs1 = new FileStream(ConfigFile, FileMode.OpenOrCreate, FileAccess.Write); fs1.Seek(0, SeekOrigin.Begin); fs1.SetLength(0); //清空文件 var serializer = new Serializer(); StreamWriter sw = new StreamWriter(fs1); serializer.Serialize(sw, ServerConfig); sw.Close(); fs1.Close(); } private void SettingForm_FormClosed(object sender, FormClosedEventArgs e) { ReLoadConfig(); } } }