Ultron.Ngrok/Ultron.Ngrok/Program.cs

164 lines
4.9 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.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace Ultron.Ngrok
{
static class Program
{
#region WindowsAPI
/// <summary>
/// 显示窗口
/// </summary>
/// <param name="hWnd"></param>
/// <param name="cmdShow"></param>
/// <returns></returns>
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(System.IntPtr hWnd, int cmdShow);
/// <summary>
/// 根据窗体句柄获得窗体标题
/// </summary>
/// <param name="hWnd"></param>
/// <param name="lpText"></param>
/// <param name="nCount"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpText, int nCount);
/// <summary>
/// 根据窗体句柄获得其进程ID
/// </summary>
/// <param name="hwnd"></param>
/// <param name="ID"></param>
/// <returns></returns>
[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
/// <summary>
/// 枚举窗体
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
[DllImport("user32")]
private static extern int EnumWindows(CallBack x, int y);
#endregion
#region
/// <summary>
/// 窗体标题
/// </summary>
public static string FormName = "uNgrok";
/// <summary>
/// 显示窗口参数
/// </summary>
private const int SW_RESTORE = 9;
/// <summary>
/// 已存在的进程实例
/// </summary>
private static Process instance = null;
private delegate bool CallBack(IntPtr hwnd, int lParam);
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//获取运行的进程
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
/// <summary>
/// 获取运行中的进程
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// 枚举窗口回调
/// </summary>
/// <param name="hwnd"></param>
/// <param name="lParam"></param>
/// <returns></returns>
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
}
}