C# Winform项目中,MainWindowHandle获取不到窗口句柄,返回值为零。请问如何解决。

时间:2021-04-02 21:27:23
在C# Winform项目中,通过Process打开了计算器(代码如下)。
Process pro = null;
pro = new Process();
pro.StartInfo.FileName = @"Calc.exe";
pro.Start();
IntPtr hwndCalc = pro.MainWindowHandle; //取不到计算器的窗口句柄,返回值为零。

pro.MainWindowHandle获取不到计算器的窗口句柄,返回值为零。
需要增加一个2秒的延时(代码如下)。
Process pro = null;
pro = new Process();
pro.StartInfo.FileName = @"Calc.exe";
pro.Start();

System.Threading.Thread.Sleep(2000);  //新增了延时2秒

IntPtr hwndCalc = pro.MainWindowHandle;  //增加了延时2秒,这样就可以获取计算器的窗口句柄


请问为什么一定要增加延时2秒后,才能获取到计算器的窗口句柄。如果不加延时2秒,可以有其它方法获取到计算器的窗口句柄?

8 个解决方案

#1


只是告诉系统去Start一个进程,但是不一定已经准备好了各种信息,所以你不一定能访问到

#2


计算器未必已经创建完毕

#3


那是不是只能用延时2秒后再取窗口句柄了呢?还是有其它的解决办法?
System.Threading.Thread.Sleep(2000);  //新增了延时2秒

#4


引用 1 楼 bdmh 的回复:
只是告诉系统去Start一个进程,但是不一定已经准备好了各种信息,所以你不一定能访问到


+1

#5


pro.Start();
pro. WaitForInputIdle();
IntPtr hwndCalc = pro.MainWindowHandle;

#6


引用 1 楼 bdmh 的回复:
只是告诉系统去Start一个进程,但是不一定已经准备好了各种信息,所以你不一定能访问到

对,未必访问到了。。。

#7


有个Refresh方法,刷新一下。如果还是不行。那就只能用win32 API,自己查找了

#8


因为你获取MainWindowHandle的时候窗口还没显示出来,用另外的线程去解决。
private void TeachForm_Shown(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(o =>
            {
                var processes = Process.GetProcessesByName("xxxx").ToList();
                if (processes.Count < 1) return;
                var process = processes[0];
                IntPtr windowHandle;
                do
                {
                    windowHandle = process.MainWindowHandle;
                    if (windowHandle == IntPtr.Zero) continue;
                    xxx.ShowWindow(windowHandle, xxx.SwMinimize);
                } while (windowHandle == IntPtr.Zero);
            }, null);
        }

#1


只是告诉系统去Start一个进程,但是不一定已经准备好了各种信息,所以你不一定能访问到

#2


计算器未必已经创建完毕

#3


那是不是只能用延时2秒后再取窗口句柄了呢?还是有其它的解决办法?
System.Threading.Thread.Sleep(2000);  //新增了延时2秒

#4


引用 1 楼 bdmh 的回复:
只是告诉系统去Start一个进程,但是不一定已经准备好了各种信息,所以你不一定能访问到


+1

#5


pro.Start();
pro. WaitForInputIdle();
IntPtr hwndCalc = pro.MainWindowHandle;

#6


引用 1 楼 bdmh 的回复:
只是告诉系统去Start一个进程,但是不一定已经准备好了各种信息,所以你不一定能访问到

对,未必访问到了。。。

#7


有个Refresh方法,刷新一下。如果还是不行。那就只能用win32 API,自己查找了

#8


因为你获取MainWindowHandle的时候窗口还没显示出来,用另外的线程去解决。
private void TeachForm_Shown(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(o =>
            {
                var processes = Process.GetProcessesByName("xxxx").ToList();
                if (processes.Count < 1) return;
                var process = processes[0];
                IntPtr windowHandle;
                do
                {
                    windowHandle = process.MainWindowHandle;
                    if (windowHandle == IntPtr.Zero) continue;
                    xxx.ShowWindow(windowHandle, xxx.SwMinimize);
                } while (windowHandle == IntPtr.Zero);
            }, null);
        }