公司的系统搭载了好多奇奇怪怪的exe,以前启动exe后,系统还能接着操作。但是后面又提出额外的需求,说是打开外部exe之后,启动exe的父界面要完全不能进行任何操作。当然按常人所想再加一句waitforexit就能决了啦,然后公司的测试超级牛逼,在exe启动的时候跑去父界面随便点了一个按钮,然后奇怪的事情就发生了:在exe关闭之后,你刚刚点击的那个按钮就会里面响应。其实最后发现不止是按钮,是整个界面都会在exe启动的过程中响应鼠标事件,但是需求要和showdialog出子界面一样的效果。虽然用户一般在exe启动的时候,也不会去乱点什么就是了,但是bug就是bug,不能不解决啊。期间想过很多办法,比如重写WndProc,比如设置flag,比如启动exe重新开线程,但是都不能很好的解决。最后受人指点如此解决了。

private void btnInvoke_Click(object sender, EventArgs e)
{
       MessageBox.Show("Hello ");
}

private void btnTest_Click(object sender, EventArgs e)
{
        this.Enabled = false;
        Thread t = new Thread(new ThreadStart(delegate
        {
             System.Diagnostics.Process exep = new System.Diagnostics.Process();
             exep.StartInfo.FileName = @"C:\Test1.exe";
             exep.EnableRaisingEvents = true;
             exep.Start();
             exep.WaitForExit();
             this.BeginInvoke(new Action(() => { this.Enabled = true; }));
        }));
        t.Start();
}

为什么会出现这种情况呢?首先启动exe的waitforexit只是将主线程(UI线程)挂起了,或者说暂时阻塞它,在exe保持启动的过程中,你对父界面进行的任何操作其实都会像排队一样被排它主线程中去,等主线程被阻塞的事情结束之后,它就会开始反应了。而且这种现象只会响应你对父界面的第一次操作,就是点一个button,在去点关闭按钮,只会响应button事件,相反,就会响应关闭事件。现在的做法是把启动exe的事情放到新的线程里面去做,不去阻塞主线程,再非活性化界面,最后用begininvoke异步执行指定的委托,在活性化界面,这样就能完全阻止那种现象的发生。不过就算如此写,waitforexit也是不能省的,之前查waitforexit是相当于挂起主线程,但是在这里把waitforexit省掉,非活性化整个界面的代码就没有用了,非活性化后面begininvoke在活性化,两部一起,等于没有做,另外省掉的话父界面就直接能操作了,所以看来waitforexit还是要搭配一起写才能实现最终效果。

C# winform启动外部exe后,如何完全阻断父界面接收事件,扩展waitforexit的更多相关文章

  1. delphi窗体启动外部exe

    uses Winapi.Windows; WinExec(PAnsiChar(Application.ExeName), sw_normal);   // PAnsiChar : string to ...

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

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

  3. 启动外部exe程序

    Process myProcess = new Process();myProcess.StartInfo.FileName = pathName;myProcess.Start();其中的pathN ...

  4. 启动LINUX系统后,进入图形化界面的命令

    1.进入xWindow的命令 $startx回车 或者修改/etc/inittab文件 cd /etc vi inittab 寻找: id:3:initdefault: 改为: id:5:initde ...

  5. 外部exe窗体嵌入winform

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; u ...

  6. 【UE4 C++】 启动 / 关闭外部exe、开启虚拟键盘

    启动/关闭外部exe 引擎自带 FPlatformProcess::CreateProc() FPlatformProcess::TerminateProc() windows api ShellEx ...

  7. windows下调用外部exe程序 SHELLEXECUTEINFO

    本文主要介绍两种在windows下调用外部exe程序的方法: 1.使用SHELLEXECUTEINFO 和 ShellExecuteEx SHELLEXECUTEINFO 结构体的定义如下: type ...

  8. sqlserver数据库触发器调用外部exe

    sqlserver数据库触发器调用外部exe,同事可以选择参入参数! sqlserver使用 master..xp_cmdshell 进行外部exe的执行. 使用master..xp_cmdshell ...

  9. C#和asp.net执行外部EXE程序

    这两天研究下.Net的执行外部EXE程序问题,就是在一个程序里通过按钮或其他操作运行起来另外一个程序,需要传入参数,如用户名.密码之类(实际上很类似单点登录,不过要简单的多的多):总结如下: 1.CS ...

随机推荐

  1. [SDOI2011]打地鼠

    题目描述 打地鼠是这样的一个游戏:地面上有一些地鼠洞,地鼠们会不时从洞里探出头来很短时间后又缩回洞中.玩家的目标是在地鼠伸出头时,用锤子砸其头部,砸到的地鼠越多分数也就越高. 游戏中的锤子每次只能打一 ...

  2. 遇到很多次,要注意区分service调用,本地用户调用这些区别

    WTSQueryUserToken返回1314   The WTSQueryUserToken function obtains the primary access token of the log ...

  3. [bzoj1607][Usaco2008 Dec]Patting Heads 轻拍牛头_筛法_数学

    Patting Heads 轻拍牛头 bzoj-1607 Usaco-2008 Dec 题目大意:题目链接. 注释:略. 想法:我们发现,位置是没有关系的. 故,我们考虑将权值一样的牛放在一起考虑,c ...

  4. MyBatis 3判断不为null

    <if test="type!=null and type!=''"> AND type = #{type} </if>

  5. 【CV论文阅读】 Fast RCNN + SGD笔记

    Fast RCNN的结构: 先从这幅图解释FAST RCNN的结构.首先,FAST RCNN的输入是包含两部分,image以及region proposal(在论文中叫做region of inter ...

  6. Swift具体解释之六----------------枚举、结构体、类

    枚举.结构体.类 注:本文为作者自己总结.过于基础的就不再赘述 ,都是亲自測试的结果.如有错误或者遗漏的地方.欢迎指正,一起学习. 1.枚举 枚举是用来定义一组通用类型的一组相关值 ,关键字enum ...

  7. 程序员之---C语言细节20(符号和有符号之间转换、两数相加溢出后数值计算)

    主要内容:无符号和有符号之间转换.两数相加溢出后数值计算 #include <stdio.h> /* 这个函数存在潜在漏洞 */ float sum_elements(float a[], ...

  8. android学习笔记(9)android程序调试学习

    相应若水老师的第十四课 一,Log日志输出 Log.v(tag,message);        //verbose模式,打印最具体的日志  Log.d(tag,message);        // ...

  9. C++对象模型——继承体系下的对象构造(第五章)

    5.2 继承体系下的对象构造 当定义一个object例如以下: T object; 时,实际上会发生什么事情呢?假设T有一个constructor(不论是由user提供或是由编译器合成),它会被调用. ...

  10. VIM学习笔记 比较文件(diff)

    比较 可以从命令行调用以下命令,来打开两个文件进行比较: vim -d file1 file2 如果已经打开了文件file1,那么可以在Vim中用以下命令,再打开另一个文件file2进行比较: :di ...