C#中通过Process启动的外部第三方程序MainWindowHandle句柄为0

原文 C#中通过Process启动的外部第三方程序MainWindowHandle句柄为0 

前几天遇到了一个在C#的winform程序中,启动一个第三方jar程序,并修改jar运行窗体的标题的问题。

大体的需求就是上面说明的那样,下面是当初设想的思路和实现代码。

STEP1

// 根据jar文件的路径,启动该jar

Process p = Process.Start(jarfilePath);

 

STEP2

// 引用WindowsAPI中SetWindowText的声明

[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowText")]

public static extern int SetWindowText(IntPtr hwnd, String lpString);

 

STEP3

// 得到启动的jar窗体的句柄

IntPtr hwnd = p.MainWindowHandle;

 

STEP4

// 改变jar窗体的标题栏文字

SetWindowText(hwnd, "标题栏新文字");

 

通过上面这四个步骤,感觉应该就可以改变启动的外部第三方程序的窗口标题栏了。

但,实际运行结果却不是想象的那样。追究为什么启动的外部第三方应用程序窗体的标题栏文字为什么没有改变,是哪行代码没被执行到,或是哪行代码出错了,在DEBUG单步执行时,却又没发现任何问题,新窗体的句柄也正常,执行完上面第四步骤的那行代码之后,看新窗体的标题栏文字,完美地被改变了。

百思不得其解,接下来的思路就是看不DEBUG单步执行时,哪行出了问题,于是在关键步骤3的后面,添加了下面的调试输出代码

Console.WriteLine("handle>>>" + hwnd);

这时的执行结果果然暴漏了问题所在,调试语句输出的MainWindowHandle为0.

 

接下来问题的关键就是找到为什么Process.MainWindowHandle得到的窗体句柄是0的问题的原因

几经google之后,发现了问题的原因,国外专家给出的原因解释,感觉还挺靠谱的。

 

The value is also zero for processes that have been hidden, that is, processes that are not visible in the taskbar. This can be the case for processes that appear as icons in the notification area, at the far right of the taskbar.

 

大体意思就是通过Process.Start得到的process还没在任务栏上创建出icon来,所以这个process貌似就被认为是不可见的,所以得到的句柄就是0.

看到这里就很容易理解为什么在DEBUG单步调试时,Process.MainWindowHandle是正常的原因了

基于上面这些解释,找到了在STEP3之前增加一下代码的解决方案。

while (p.MainWindowHandle == IntPtr.Zero)

                {

                    System.Threading.Thread.Sleep(100);

                }

 

到此,问题解决。但仍残留了一个值得思考的问题。在Process类下有WaitForInputIdle()这个方法,看msdn上的解释貌似也是等待,我尝试着不用上面那个while循环,而用p.WaitForInputIdle();来代替,结果是不行的。

为什么呢,希望有对此熟悉的朋友能给个解释。

时间: 2024-10-09 03:01:43

C#中通过Process启动的外部第三方程序MainWindowHandle句柄为0的相关文章

如何发送CTRL+C终止由Process启动的DOS命令?

问题描述 手动操作:在DOS命令提示符下执行一个命令,该命令是交互式的,需要手动键入CTRL+C才能终止,而DOS窗口依然不被关闭.现在要用C#程序自动完成,由Process类启动命令,但不知道如何发送CTRL+C给这个已经启动的命令来终止它. 解决方案 解决方案二:Process启动的那个可以直接调用Kill方法或者你的问题是向命令窗口写入CTRL+C,那么这是标准输入的问题,重定向标准输入可以由代码写入或者你可以模拟键盘的输入,那就不是几行代码的问题了解决方案三:在程序里加个热键?解决方案四

使用Delphi启动和关闭外部应用程序

Delphi与Windows平台紧密结合,编译代码快速高效.作为一种可视化的面向对象开发工具,Delphi可以帮助程序员更轻松.更快速地编写各种Windows应用程序.而且通过编程可以方便地调用其它语言编写的动态库或应用程序,并在不需要时关闭这些外部程序.这一点对许多编程人员非常有用,例如,在采用Delphi进行软件开发的同时,可能需要调用以前采用其它工具开发的应用程序,以免再次重新编写代码,或者需要调用Windows中的记事本和计算器等工具,以便在程序运行过程中记录信息或进行计算等. 在Del

Node.js中的process.nextTick使用实例

  这篇文章主要介绍了Node.js中的process.nextTick使用实例,nextTick函数有什么用.怎么用.和setTimeout有什么区别呢,本文就讲解了这些知识,需要的朋友可以参考下 我已经不记得是在哪里第一次看到process.nextTick这个玩意的调用了,哦,应该是在nodejs官方的process文档里看到的.当时就不理解这东西是干嘛的了,都已经有setTimeout了,还需要这个函数干嘛.而且从根本上来说,这个函数又是干嘛的?和setTimeout有什么区别? sta

java-Java如何获取启动的外部进程的ID

问题描述 Java如何获取启动的外部进程的ID java使用Runtime执行命令启动了一个外部程序,如何获取到这个外部进程的ID?使用 ManagementFactory.getRuntimeMXBean().getName();只能获取到当前进程的ID 解决方案 第一次遇到这个问题,探索中--

Process启动一个外部程序,如何使这个外部程序的主窗体停靠在我需要的位置

问题描述 Process启动一个外部程序,如何使这个外部程序的主窗体停靠在我需要的位置 解决方案 解决方案二:使用Process调用外部程序的时候指定ProcessStartInfo对象,这个对象中有你所需要的东西解决方案三:能否说得明白些,没找到可以直接定位的属性!解决方案四:可能要用API吧不知道framework里有什么方法mark解决方案五:关注,同样问题.....解决方案六:System.Diagnostics.Process.Start启动外部程序,至于外部程序主窗体停靠位置你要在那

在PHP中以root身份运行外部命令[转自linuxaid]

Hunte 2001年4月15日 在PHP中运行只有root用户才可以运行的外部程序,一直是个老问题,用常规的办法很难实现.这是因为一般情况下,PHP是作为APACHE的一个模块的,也就是说,PHP是APACHE的一部分,而APACHE除了suEXEC机制外,是不能以不同的用户ID来执行命令的,但suEXEC机制只能CGI有效. 网上曾经有一篇文章,说用调用"su - -c COMMAND"可以实现,但经过多次试验,发现不行,因为su命令必须在STDIN上输入root的密码. 怎么办?

在PHP中以root身份运行外部命令[转自奥索]

  在PHP中运行只有root用户才可以运行的外部程序,一直是个老问题,用常规的办法很难实现.这是因为一般情况下,PHP是作为APACHE的一个模块的,也就是说,PHP是APACHE的一部分,而APACHE除了suEXEC机制外,是不能以不同的用户ID来执行命令的,但suEXEC机制只能CGI有效. 网上曾经有一篇文章,说用调用"su - -c COMMAND"可以实现,但经过多次试验,发现不行,因为su命令必须在STDIN上输入root的密码. 怎么办?用常规的方法难以奏效,只能再想

在PHP中以root身份运行外部命

在PHP中运行只有root用户才可以运行的外部程序,一直是个老问题,用常规的办法很难实现.这是因为一般情况下,PHP是作为APACHE的一个模块的,也就是说,PHP是APACHE的一部分,而APACHE除了suEXEC机制外,是不能以不同的用户ID来执行命令的,但suEXEC机制只能CGI有效. 网上曾经有一篇文章,说用调用"su - -c COMMAND"可以实现,但经过多次试验,发现不行,因为su命令必须在STDIN上输入root的密码. 怎么办?用常规的方法难以奏效,只能再想其它

C#中利用process类调用外部程序以及执行dos命令

程序|执行 c#中的Process类可方便的调用外部程序,所以我们可以通过调用cmd.exe程序 加入参数 "/c " + 要执行的命令来执行一个dos命令(/c代表执行参数指定的命令后关闭cmd.exe /k参数则不关闭cmd.exe)  1         private string RunCmd(string command)     2         { 3             //實例一個Process類,啟動一個獨立進程 4             Process