实现的功能是通过快捷方式唤醒程序窗口,代码要根据实际需求改动一下,主要原理:通过程序线程得到窗口句柄,使用win32api下发显示指令。
#region 唤醒程序
// 显示/隐藏窗口
[DllImport("user32.dll", EntryPoint = "ShowWindow")]
static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
// 隐藏/显示窗口(flag:1显示;0隐藏)
private static void ShowOrHiddenWin(IntPtr handle, uint flag)
{
ShowWindow(handle, flag);
}
private static bool starting()
{
int count = 0;
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
//遍历程序的同名进程组
foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName(process.ProcessName))
{
if (p.Id != process.Id && (p.StartTime - process.StartTime).TotalMilliseconds <= 0)
{
count++;
}
}
if (count >= System.Windows.Forms.Screen.AllScreens.Length)//启动个数大于屏幕数(如果是唯一启动将这个if去掉)
{
foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName(process.ProcessName))
{
if (p.Id != process.Id && (p.StartTime - process.StartTime).TotalMilliseconds <= 0)
{
//p.MainWindowHandle;//隐藏窗口的句柄无法获取
CurrentProcess currentProcess = new CurrentProcess();
IntPtr intPtr = currentProcess.GetCurrentWindowHandle(p);//获取窗口句柄(包括隐藏窗口)重点代码
if (intPtr != IntPtr.Zero)
ShowOrHiddenWin(intPtr, 1);
}
}
return false;
}
return true;
}
#endregion
CurrentProcess.cs 代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace beelight.DataView
{
class CurrentProcess
{
private static Hashtable processWnd = null;
public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam);
static CurrentProcess()
{
if (processWnd == null)
{
processWnd = new Hashtable();
}
}
[DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)]
public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam);
[DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId);
[DllImport("user32.dll", EntryPoint = "IsWindow")]
public static extern bool IsWindow(IntPtr hWnd);
[DllImport("kernel32.dll", EntryPoint = "SetLastError")]
public static extern void SetLastError(uint dwErrCode);
public IntPtr GetCurrentWindowHandle(Process process)
{
IntPtr ptrWnd = IntPtr.Zero;
try
{
uint uiPid = (uint)process.Id; // 进程 ID
object objWnd = processWnd[uiPid];
if (objWnd != null)
{
ptrWnd = (IntPtr)objWnd;
if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd)) // 从缓存中获取句柄
{
return ptrWnd;
}
else
{
ptrWnd = IntPtr.Zero;
}
}
bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid);
// 枚举窗口返回 false 并且没有错误号时表明获取成功
if (!bResult && Marshal.GetLastWin32Error() == 0)
{
objWnd = processWnd[uiPid];
if (objWnd != null)
{
ptrWnd = (IntPtr)objWnd;
}
}
}
catch
{
}
return ptrWnd;
}
private static bool EnumWindowsProc(IntPtr hwnd, uint lParam)
{
uint uiPid = 0;
if (GetParent(hwnd) == IntPtr.Zero)
{
GetWindowThreadProcessId(hwnd, ref uiPid);
if (uiPid == lParam) // 找到进程对应的主窗口句柄
{
processWnd[uiPid] = hwnd; // 把句柄缓存起来
SetLastError(0); // 设置无错误
return false; // 返回 false 以终止枚举窗口
}
}
return true;
}
}
}
主函数调用 starting() 即可,快去试试吧。