diff --git a/Ultron.Ngrok/Form/AboutBox.Designer.cs b/Ultron.Ngrok/Form/AboutBox.Designer.cs index 7de65c4..1a2371c 100644 --- a/Ultron.Ngrok/Form/AboutBox.Designer.cs +++ b/Ultron.Ngrok/Form/AboutBox.Designer.cs @@ -31,6 +31,7 @@ this.labelProductName = new System.Windows.Forms.Label(); this.labelVersion = new System.Windows.Forms.Label(); this.labelCopyright = new System.Windows.Forms.Label(); + this.labelEmail = new System.Windows.Forms.Label(); this.okButton = new System.Windows.Forms.Button(); this.tableLayoutPanel.SuspendLayout(); this.SuspendLayout(); @@ -42,16 +43,18 @@ this.tableLayoutPanel.Controls.Add(this.labelProductName, 0, 0); this.tableLayoutPanel.Controls.Add(this.labelVersion, 0, 1); this.tableLayoutPanel.Controls.Add(this.labelCopyright, 0, 2); - this.tableLayoutPanel.Controls.Add(this.okButton, 0, 3); + this.tableLayoutPanel.Controls.Add(this.labelEmail, 0, 3); + this.tableLayoutPanel.Controls.Add(this.okButton, 0, 4); this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel.Location = new System.Drawing.Point(9, 8); this.tableLayoutPanel.Name = "tableLayoutPanel"; - this.tableLayoutPanel.RowCount = 4; + this.tableLayoutPanel.RowCount = 5; this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25F)); this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25F)); - this.tableLayoutPanel.Size = new System.Drawing.Size(223, 100); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F)); + this.tableLayoutPanel.Size = new System.Drawing.Size(223, 113); this.tableLayoutPanel.TabIndex = 0; // // labelProductName @@ -69,7 +72,7 @@ // labelVersion // this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill; - this.labelVersion.Location = new System.Drawing.Point(6, 25); + this.labelVersion.Location = new System.Drawing.Point(6, 21); this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); this.labelVersion.MaximumSize = new System.Drawing.Size(0, 16); this.labelVersion.Name = "labelVersion"; @@ -81,7 +84,7 @@ // labelCopyright // this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill; - this.labelCopyright.Location = new System.Drawing.Point(6, 50); + this.labelCopyright.Location = new System.Drawing.Point(6, 42); this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); this.labelCopyright.MaximumSize = new System.Drawing.Size(0, 16); this.labelCopyright.Name = "labelCopyright"; @@ -90,11 +93,23 @@ this.labelCopyright.Text = "版权"; this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // + // labelEmail + // + this.labelEmail.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelEmail.Location = new System.Drawing.Point(6, 63); + this.labelEmail.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); + this.labelEmail.MaximumSize = new System.Drawing.Size(0, 16); + this.labelEmail.Name = "labelEmail"; + this.labelEmail.Size = new System.Drawing.Size(214, 16); + this.labelEmail.TabIndex = 25; + this.labelEmail.Text = "Email"; + this.labelEmail.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // // okButton // this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.okButton.Location = new System.Drawing.Point(145, 78); + this.okButton.Location = new System.Drawing.Point(145, 91); this.okButton.Name = "okButton"; this.okButton.Size = new System.Drawing.Size(75, 19); this.okButton.TabIndex = 24; @@ -106,7 +121,7 @@ this.AcceptButton = this.okButton; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(241, 116); + this.ClientSize = new System.Drawing.Size(241, 129); this.Controls.Add(this.tableLayoutPanel); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; @@ -129,5 +144,6 @@ private System.Windows.Forms.Label labelVersion; private System.Windows.Forms.Label labelCopyright; private System.Windows.Forms.Button okButton; + private System.Windows.Forms.Label labelEmail; } } diff --git a/Ultron.Ngrok/Form/AboutBox.cs b/Ultron.Ngrok/Form/AboutBox.cs index 929c687..0b8e1f4 100644 --- a/Ultron.Ngrok/Form/AboutBox.cs +++ b/Ultron.Ngrok/Form/AboutBox.cs @@ -18,6 +18,7 @@ namespace Ultron.Ngrok this.labelProductName.Text = AssemblyProduct; this.labelVersion.Text = String.Format("版本 {0}", AssemblyVersion); this.labelCopyright.Text = AssemblyCopyright; + this.labelEmail.Text = "邮箱 wixy@qq.com"; } #region 程序集特性访问器 @@ -104,6 +105,5 @@ namespace Ultron.Ngrok { this.Close(); } - } } diff --git a/Ultron.Ngrok/Form/SettingForm.cs b/Ultron.Ngrok/Form/SettingForm.cs index f15e8dc..373724c 100644 --- a/Ultron.Ngrok/Form/SettingForm.cs +++ b/Ultron.Ngrok/Form/SettingForm.cs @@ -184,11 +184,18 @@ namespace Ultron.Ngrok 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); - + try + { + string configText = File.ReadAllText(ConfigFile, Encoding.UTF8); + var input = new StringReader(configText); + //var deserializer = new Deserializer(namingConvention: new CamelCaseNamingConvention()); + var deserializer = new Deserializer(); + ServerConfig = deserializer.Deserialize(input); + } + catch(Exception ex) + { + MessageBox.Show(ex.InnerException.Message); + } LoadConfig(); } diff --git a/Ultron.Ngrok/FormMain.Designer.cs b/Ultron.Ngrok/FormMain.Designer.cs index d65783a..034478e 100644 --- a/Ultron.Ngrok/FormMain.Designer.cs +++ b/Ultron.Ngrok/FormMain.Designer.cs @@ -115,7 +115,7 @@ // this.notifyIcon.ContextMenuStrip = this.notifyMenuStrip; this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); - this.notifyIcon.Text = "uNgrok"; + this.notifyIcon.Text = Program.FormName; this.notifyIcon.Visible = true; this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.NotifyIcon_MouseDoubleClick); // @@ -156,10 +156,9 @@ this.MaximizeBox = false; this.Name = "FormMain"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "uNgrok"; + this.Text = Program.FormName; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormMain_FormClosing); this.Load += new System.EventHandler(this.FormMain_Load); - this.SizeChanged += new System.EventHandler(this.FormMain_SizeChanged); this.topMenuStrip.ResumeLayout(false); this.topMenuStrip.PerformLayout(); this.notifyMenuStrip.ResumeLayout(false); diff --git a/Ultron.Ngrok/FormMain.cs b/Ultron.Ngrok/FormMain.cs index bfcf375..c64c875 100644 --- a/Ultron.Ngrok/FormMain.cs +++ b/Ultron.Ngrok/FormMain.cs @@ -145,24 +145,18 @@ namespace Ultron.Ngrok private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) { - if (WindowState == FormWindowState.Minimized) - { - //还原窗体显示 - WindowState = FormWindowState.Normal; - //激活窗体并给予它焦点 - this.Activate(); - //任务栏区显示图标 - this.ShowInTaskbar = true; - //托盘区图标隐藏 - notifyIcon.Visible = false; - } + 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) { - WindowState = FormWindowState.Minimized; + notifyIcon.Visible = true; + this.Hide(); e.Cancel = true; } else @@ -179,19 +173,7 @@ namespace Ultron.Ngrok } } } - - private void FormMain_SizeChanged(object sender, EventArgs e) - { - //判断是否选择的是最小化按钮 - if (WindowState == FormWindowState.Minimized) - { - //隐藏任务栏区图标 - this.ShowInTaskbar = false; - //图标显示在托盘区 - notifyIcon.Visible = true; - } - } - + private void 退出ToolStripMenuItem_Click(object sender, EventArgs e) { if (MessageBox.Show("是否确认退出程序?", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK) @@ -327,30 +309,38 @@ namespace Ultron.Ngrok public void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) { - StreamReader read = new StreamReader(e.Result); - string str = read.ReadToEnd(); - if (str.Contains("\"code\":1")) - return; - else + try { - if (MessageBox.Show("检测到新版本,立即更新?", "版本更新", MessageBoxButtons.YesNo) == DialogResult.Yes) + StreamReader read = new StreamReader(e.Result); + string str = read.ReadToEnd(); + if (str.Contains("\"code\":1")) + return; + else { - int verStart = str.IndexOf("\"version\":\"") + 11; - int verEnd = str.IndexOf("\",\"title\""); - string version = str.Substring(verStart, verEnd - verStart); - string updateExe = Directory.GetCurrentDirectory() + @"\autoUpdate.exe"; - if (File.Exists(updateExe)) + if (MessageBox.Show("检测到新版本,立即更新?", "版本更新", MessageBoxButtons.YesNo) == DialogResult.Yes) { - File.Delete(updateExe); + int verStart = str.IndexOf("\"version\":\"") + 11; + int verEnd = str.IndexOf("\",\"title\""); + string version = str.Substring(verStart, verEnd - verStart); + 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(); + + RunUpdateProgram(version); } - - FileStream stream = new FileStream(updateExe, FileMode.OpenOrCreate); - stream.Write(Resources.autoUpdate, 0, Resources.autoUpdate.Length); - stream.Close(); - - RunUpdateProgram(version); } } + catch(Exception ex) + { + MessageBox.Show($"无法检测更新:{ex.InnerException.Message}"); + } + } public void RunUpdateProgram(string verion) diff --git a/Ultron.Ngrok/Program.cs b/Ultron.Ngrok/Program.cs index e3840cb..ced3835 100644 --- a/Ultron.Ngrok/Program.cs +++ b/Ultron.Ngrok/Program.cs @@ -1,13 +1,76 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; using System.Windows.Forms; namespace Ultron.Ngrok { static class Program { + #region WindowsAPI + + /// + /// 显示窗口 + /// + /// + /// + /// + [DllImport("User32.dll")] + private static extern bool ShowWindowAsync(System.IntPtr hWnd, int cmdShow); + + /// + /// 根据窗体句柄获得窗体标题 + /// + /// + /// + /// + /// + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpText, int nCount); + + /// + /// 根据窗体句柄获得其进程ID + /// + /// + /// + /// + [DllImport("User32.dll", CharSet = CharSet.Auto)] + private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID); + + /// + /// 枚举窗体 + /// + /// + /// + /// + [DllImport("user32")] + private static extern int EnumWindows(CallBack x, int y); + + #endregion + + #region 属性字段委托 + + /// + /// 窗体标题 + /// + public static string FormName = "uNgrok"; + + /// + /// 显示窗口参数 + /// + private const int SW_RESTORE = 9; + + /// + /// 已存在的进程实例 + /// + private static Process instance = null; + + private delegate bool CallBack(IntPtr hwnd, int lParam); + + #endregion + /// /// 应用程序的主入口点。 /// @@ -16,7 +79,85 @@ namespace Ultron.Ngrok { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new FormMain()); + + //获取运行的进程 + instance = RunningInstance(); + if (instance == null) + { + //没有进程在运行 + Application.Run(new FormMain()); + } + else + { + //是否托盘化, 托盘状态窗口句柄为0 + if (instance.MainWindowHandle.ToInt32() != 0) + { + //调用api函数,正常显示窗口 + ShowWindowAsync(instance.MainWindowHandle, SW_RESTORE); + } + else + { + CallBack callback = new CallBack(Report); + EnumWindows(callback, 0); + } + + Environment.Exit(Environment.ExitCode); + } } + + #region 方法 + + /// + /// 获取运行中的进程 + /// + /// + private static Process RunningInstance() + { + Process current = Process.GetCurrentProcess(); + Process[] processes = Process.GetProcessesByName(current.ProcessName); + //遍历与当前进程名称相同的进程列表 + foreach (Process process in processes) + { + //如果实例已经存在则忽略当前进程 + if (process.Id != current.Id) + { + //保证要打开的进程同已经存在的进程来自同一文件路径 + if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName) + { + //返回已经存在的进程 + return process; + } + } + } + return null; + } + + /// + /// 枚举窗口回调 + /// + /// + /// + /// + private static bool Report(IntPtr hwnd, int lParam) + { + //获得窗体标题 + StringBuilder sb = new StringBuilder(100); + GetWindowText(hwnd, sb, sb.Capacity); + + //获取进程ID + GetWindowThreadProcessId(hwnd, out int calcID); + + //标题栏、进程id符合 + if ((sb.ToString() == FormName) && (instance != null) && (calcID == instance.Id)) + { + //调用api函数,正常显示窗口 + ShowWindowAsync(hwnd, SW_RESTORE); + return false; + } + + return true; + } + + #endregion } } diff --git a/Ultron.Ngrok/Properties/AssemblyInfo.cs b/Ultron.Ngrok/Properties/AssemblyInfo.cs index 583893b..67a167e 100644 --- a/Ultron.Ngrok/Properties/AssemblyInfo.cs +++ b/Ultron.Ngrok/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, // 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.0.0")] -[assembly: AssemblyFileVersion("1.1.0.0")] +[assembly: AssemblyVersion("1.2.0.0")] +[assembly: AssemblyFileVersion("1.2.0.0")]