1、封装一个句柄操作类IntPtrHelper.cs
public static class IntPtrHelper
{
public const int WS_SHOWMAXIMIZE = 3; //最大化显示窗口
public const int WS_SHOW = 5;//以原来大小和位置显示
/// <summary>
/// 获取所有窗体
/// </summary>
/// <returns></returns>
public static List<WindowInfo> GetAllDesktopWindows()
{
List<WindowInfo> wndList = new List<WindowInfo>();
//enum all desktop windows
EnumWindows(delegate (IntPtr hWnd, int lParam)
{
WindowInfo wnd = new WindowInfo();
StringBuilder sb = new StringBuilder(256);
//get hwnd
wnd.HWnd = hWnd;
//get window name
GetWindowTextW(hWnd, sb, sb.Capacity);
wnd.WindowName = sb.ToString();
//get window class
GetClassNameW(hWnd, sb, sb.Capacity);
wnd.ClassName = sb.ToString();
//add it into list
wndList.Add(wnd);
return true;
}, 0);
return wndList;
}
/// <summary>
/// 定义委托
/// </summary>
/// <param name="hWnd">The h WND.</param>
/// <param name="lParam">The l parameter.</param>
/// <returns></returns>
private delegate bool Wndenumproc(IntPtr hWnd, int lParam);
/// <summary>
///枚举所有的窗体
/// </summary>
/// <param name="lpEnumFunc">The lp enum function.</param>
/// <param name="lParam">The l parameter.</param>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern bool EnumWindows(Wndenumproc lpEnumFunc, int lParam);
/// <summary>
///查找窗体tit
/// </summary>
/// <param name="hWnd">The h WND.</param>
/// <param name="lpString">The lp string.</param>
/// <param name="nMaxCount">The n maximum count.</param>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
/// <summary>
///查找窗体类名
/// </summary>
/// <param name="hWnd">The h WND.</param>
/// <param name="lpString">The lp string.</param>
/// <param name="nMaxCount">The n maximum count.</param>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
/// <summary>
///窗体置顶
/// </summary>
/// <param name="hWnd">The h WND.</param>
/// <param name="hWndInsertAfter">The h WND insert after.</param>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
/// <param name="Width">The width.</param>
/// <param name="Height">The height.</param>
/// <param name="flags">The flags.</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
/// <summary>
/// 该函数设置由不同线程产生的窗口的显示状态。
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分。</param>
/// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零。</returns>
[DllImport("User32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
/// <summary>
/// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。
/// </summary>
/// <param name="hWnd">将被激活并被调入前台的窗口句柄。</param>
/// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零。</returns>
[DllImport("User32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
/// <summary>
/// 根据窗口标题查找窗体
/// </summary>
/// <param name="lpClassName"></param>
/// <param name="lpWindowName"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
}
/// <summary>
/// 窗体信息
/// </summary>
public struct WindowInfo
{
/// <summary>
/// The h WND
/// </summary>
public IntPtr HWnd;
/// <summary>
/// The window name
/// </summary>
public string WindowName;
/// <summary>
/// The class name
/// </summary>
public string ClassName;
}1、改造Program.cs的Main方法
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Process instance = RunningInstance();
if (instance == null)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Frm_Main());
}
else
{
HandleRunningInstance(instance);
}
}这里面涉及到两个方法,一个是RunningInstance(),获取正在运行的程序进程;一个是HandleRunningInstance(),激活正在运行的程序。
看看怎么实现的:
/// <summary>
/// 获取正在运行的实例,没有运行的实例返回null;
/// </summary>
public static Process RunningInstance()
{
try
{
Process current = Process.GetCurrentProcess();
var processes = Process.GetProcessesByName(current.ProcessName).Where(x => x.Id != current.Id).ToList();
foreach (Process process in processes)
{
if (process?.MainModule?.FileName == current.MainModule.FileName)
{
return process;
}
}
return null;
}
catch
{
return null;
}
} /// <summary>
/// 显示已运行的程序。
/// </summary>
public static void HandleRunningInstance(Process instance)
{
IntPtr hwnd = instance.MainWindowHandle;
if (hwnd == IntPtr.Zero)
{
var wins = IntPtrHelper.GetAllDesktopWindows();
string winname = "窗体名称";
if (wins.Exists(x => x.WindowName.Contains(winname)))
{
var cla = wins.Where(x => x.WindowName.Contains(winname)).ToList();
cla.ForEach(x =>
{
IntPtrHelper.ShowWindowAsync(x.HWnd, IntPtrHelper.WS_SHOWMAXIMIZE);
IntPtrHelper.SetForegroundWindow(x.HWnd);
});
}
}
else
{
IntPtrHelper.ShowWindowAsync(hwnd, IntPtrHelper.WS_SHOWMAXIMIZE);
IntPtrHelper.SetForegroundWindow(hwnd);
}
}激活正在运行的程序这里,我们遇到点问题,当程序缩小到托盘的时候,获取不到句柄信息,导致激活不了窗体
所以我们当获取到的句柄为IntPtr.Zero的时候,通过窗体名称遍历一下所有的进程,找到指定的进程,再激活
川公网安备 51010702003150号
留下您的脚步
最近评论