2019-04-01 08:17:56 +08:00
|
|
|
|
using System;
|
2019-08-30 09:37:01 +08:00
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Text;
|
2019-04-01 08:17:56 +08:00
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
|
|
|
|
namespace Ultron.Ngrok
|
|
|
|
|
{
|
|
|
|
|
static class Program
|
|
|
|
|
{
|
2019-08-30 09:37:01 +08:00
|
|
|
|
#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
|
|
|
|
|
|
2019-04-01 08:17:56 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 应用程序的主入口点。
|
|
|
|
|
/// </summary>
|
|
|
|
|
[STAThread]
|
|
|
|
|
static void Main()
|
|
|
|
|
{
|
|
|
|
|
Application.EnableVisualStyles();
|
|
|
|
|
Application.SetCompatibleTextRenderingDefault(false);
|
2019-08-30 09:37:01 +08:00
|
|
|
|
|
|
|
|
|
//获取运行的进程
|
|
|
|
|
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);
|
|
|
|
|
}
|
2019-04-01 08:17:56 +08:00
|
|
|
|
}
|
2019-08-30 09:37:01 +08:00
|
|
|
|
|
|
|
|
|
#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
|
2019-04-01 08:17:56 +08:00
|
|
|
|
}
|
|
|
|
|
}
|