原文 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();来代替,结果是不行的。
为什么呢,希望有对此熟悉的朋友能给个解释。

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

  1. python 怎么启动一个外部命令程序, 并且不阻塞当前进程

    http://www.myexception.cn/perl-python/1278887.html http://blog.chinaunix.net/uid-25979788-id-3081912 ...

  2. 在程序中通过Process启动外部exe的方法及注意事项

    启动外部进程的方法: /// <summary> /// 启动外部进程 /// </summary> /// <param name="path"&g ...

  3. 在C#中使用 SendMessage 实现操作外部其他程序上的控件教程

    一.C#代码实现 本案例使用的是c# winform .NET Framework 4.7.2 首先我们声明一个寻找窗体的函数 [DllImport("User32.dll", E ...

  4. 关于用python作为第三方程序,来调用shell命令的问题,以及返回值格式解析

    1.用python语言作为第三方,调用shell 在python2.x中,可以通过包commands来进行调用shell命令.如下: cmd就是你要调用的shell命令,把环境配置好,输入正确的命令格 ...

  5. C#中启动外部应用程序

    C#中我们可以通过Process类直接启动外部应用程序 代码如下: Process p = new Process();                    p.StartInfo.FileName ...

  6. [C#]做服务使用Process启动外部程序没窗体

    这几天会到一个需要,要时时侦测文件生成,并上传到Server上,侦测文件生成使用的FileSystemWatch.但是时时运行遇到了问题,程序可能会人为退出或者意外终止,使用一个进程监控程序的监程,也 ...

  7. Android如何做到应用程序图标隐藏,由第三方程序启动

    在你App的AndroidManifest.xml中,将启动页做如下修改 <intent-filter> <action android:name="android.int ...

  8. 在Visual Studio中快速启动调试Web应用程序

    原文:http://blog.csdn.net/effun/article/details/2638535 到2005,Visual Studio在启动调试的功能上进行了一些改善,不过因为只是简单的一 ...

  9. 在 C# 中使用文件名启动应用程序

     本文演示了如何启动与某一给定文档扩展名或文件类型关联的应用程序而又无须知道该关联应用程序的名称或位置.例如,您可以用一个与 .bmp 文件扩展名关联的应用程序启动 Arcade.bmp 文件,多 ...

随机推荐

  1. WebService使用的一些总结

    什么是WebService: 这个不用我在这里废话,网上的资料一搜一大把,如果你没有接触过这方面的知识,你可以先去网上查一下.这里我只想说一下我印象比较深刻的几点: WebService是基于soap ...

  2. mac osx 10.9 ftp server端口

    开启 FTP Serversudo -s launchctl load -w /System/Library/LaunchDaemons/ftp.plist 关闭 FTP Serversudo -s ...

  3. Linux中的读函数与块高速缓存

    为了提高Linux块设备读写的效率,Unix会在内存中建立块高速缓存,块高速缓存存储了系统最近读的数据块和刚刚写入的数据块,也就是说IO访问其实是和块高速缓存打交道的(直接IO除外),块高速缓存会适时 ...

  4. 两阶段提交及JTA

    两阶段提交及JTA 分布式事务 分布式事务简介 分布式事务是指会涉及到操作多个数据库(或者提供事务语义的系统,如JMS)的事务.其实就是将对同一数据库事务的概念扩大到了对多个数据库的事务.目的是为了保 ...

  5. 一步一步学python(四) - 字典

    1.字典的使用 创建字典:phonebook = {'Alice': '1234' , 'Beth':'9120'} 2.dict函数 >>>items = [('name','Gu ...

  6. fragment低版本

    http://bbs.csdn.net/topics/390271980 Fragment框架开发东西确实很方便,但是恼人的是从4.0才开始支持.以前的版本必须用兼容模式开发,本人在网上找了大量资料, ...

  7. js设计模式

    http://www.csdn.net/article/2011-09-02/303983 阐明JavaScript设计模式.CSDN研发频道对此文进行了整理选取部分内容,供开发者学习.参考. 内容如 ...

  8. git 拉取远程分之到本地

    git checkout -b newbranch_name --track origin/feature/newbranch_name 如果遇到类似: fatal: git checkout: up ...

  9. linux分区,文件系统,目录结构概述

    1.Linux中如何表示硬盘,分区 Linux内核读取光驱,硬盘等资源时均通过“设备文件”的形式进行,因此在linux系统中,将硬 盘和分区表示为不同的文件.具体表述形式如下: 硬盘:对于IDE接口的 ...

  10. linux命令之uname

    uname是linux中查询系统基本信息的命令. 命令形式: uname [选项] 选项包括:(若不跟任何选项:则默认-s选项) -s, --kernel-name 输出内核名称   -n, --no ...