唤醒隐藏程序和QQ微信效果一样

实现的功能是通过快捷方式唤醒程序窗口,代码要根据实际需求改动一下,主要原理:通过程序线程得到窗口句柄,使用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() 即可,快去试试吧。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值