当应用程序不是以 UserInteractive 模式运行时显示模式对话框或窗体是无效操作

Windows UserInteractive 模式相关问题调试

当应用程序不是以 UserInteractive 模式运行时显示模式对话框或窗体是无效操作

发生背景

VS2005下编写的Agent.exe程序,需要访问外部公司的WebService,近期因为外部公司升级TLS的访问协议,运行当前Agent.exe的服务器WinSer2003无法支持,寻找替代方案。简单直接的思路是将Agent.exe程序转移到WinSer2012高版本的运行服务器上执行,对应的.Net Framework会自动支持相关协议,中间也是经历了一些调试的困难,以为是解决了问题,没想到还是存在遗留,果真是有很多细节没有经历便无所积累。

  1. 当前Agent.exe在cmd命令下直接调用都运行正常;
  2. 改成任务计划定期执行,就显示了这个“UserInteractive”的问题;
  3. 调用命令:程序路径*****.Agent.exe -300 -min -auto;
  4. 代码逻辑:此处是在Agent.exe中调用外部WebService,通过Web引用相关方法实现。

主要问题

完全相同的指令,只是更换了执行的形式,就一个成功一个失败。说实话像这种问题,若非实际中碰到,仅凭理论学习感觉很难避免。不知道对相关基层原理研究非常透彻的大神们,是否觉得太小儿科。我们一般的搬砖人只能查查查、试试试了。
在这里插入图片描述

分析思路

1.首先消息来源是Windows.Forms,所以一个思路是去掉Forms可以解决。但似乎无法解释cmd下可以运行这件事,因为这个也是存在Forms的情况就能成功的。
2.还有说法是引用了.Net Reactor加密完的dll引起的问题,但是我们两种引用形式都是调用的加密dll,cms形式下是可调用的,这无法解释上述疑虑。
3.再有说法是,WebService中引用了MessageBox.Show()的内容,这个也与此处提供的背景不同,当前情况是在Winform的Agent.exe中调用WebService,确实有MessageBox.Show()这么一行代码,但是它是属于另一个选择分支,在上面所描述的两种执行方式中,都没有走这条分支。

解决方案

1.建一步了解问题: Environment.UserInteractive 属性,如果当前进程在用户交互模式中运行,则为true ;否则为 false。此UserInteractive 属性报告 false 的 Windows 进程或服务(如 IIS)在没有用户界面的情况下运行。如果此属性为 false ,则不会显示模式对话框或消息框,因为没有可供用户与之交互的图形用户界面。
2.按照上述3的描述,怀疑MessageBox.Show()和任务计划执行方式组合出现的问题,通过注释MessageBox.Show(),执行任务计划,甚至提升任务计划以最高权限运行,还是无法解决问题。至此确定了开始的分析思路方向有问题,重新做如下程序执行顺序调整,这一步的结果是上传可以完成,所以问题出在本地备份。
在这里插入图片描述
调整顺序WebService上传成功了,看起来问题出在本地保存。在这里插入图片描述
3.那么同样的疑问可能要去继续考察“本地保存”模块了,为什么cmd可以,任务计划不行?经历以上折腾,对问题有了更精确的定位。通过添加MessageBox.Show()调试Agent.exe;发现任务计划中无法Show窗体,这里可以说是有一个颠覆性的认识,一直以来的记忆中的经验任务计划是可以显示Show信息的,难道不可以嘛?重新在VS2005和VS2010中尝试任务计划Show信息,确实不会显示,只有cmd命令下直接运行exe可以Show()。
4.至此确认的问题是任务计划不能执行MessageBox.Show()命令?其实追踪到这个地步已经可以解决大部分疑惑了,一定程度上缓解了强迫症。但是近来有个”打破沙锅追到底“的习惯,还想再来试着追踪一下,MessageBox.Show()是为了追踪程序执行步骤,这个没有效果的话,那可以采用文件流写日志替代?
5.通过StreamWriter追踪记录,将代码执行进度记录在txt文件中,确实有了新的进展,最终把问题聚焦在了一行代码上。那这一行代码也不是简单的一行代码,它其实是引用的一个封装dll导出Excel的功能,问题肯定是出在这里了?目前的导出是借助Office组件,调整成NPOI组件,导出就没有问题了。至此不知不觉更加明确的问题的地点,也找到了另一个路径解决问题。但似乎对最开始的疑虑还是没有解释。
在这里插入图片描述
6.此时又重新回到交互模式这里进行咬文嚼字。
什么是交互?为何要交互?
什么是交互?即:用户和计算机能够互动,计算机显示给用户一个可操作的接口(如:命令行窗口或者图形操作界面),用户通过该接口向计算机发送一个指令,计算机根据用户的指令执行下一步操作,如此便产生了互动。
为何要交互?计算机运行有两种方式,一种是前端可见的(显示器),还有一种是后端的(程序在运行,但是不对前端显示,前端不可见)。所以有时候,输入指令成功了,但是前端却不能显示,这是因为程序在后端执行了。
CMD属于交互模式,任务计划不是交互模式。现在大概推断问题是,当前新环境下,Office组件导出Excel过程中是有一些问题,但是在CMD下是可以导出的,程序中间跳出个问题但是依然能导出表格这个情况不算奇怪,而任务计划执行时遇到问题会弹出MessageBox.Show()异常,但又因为不是交互模式,就造成程序无法继续下去了。那么Excel中导出中的这个问题会是什么?CMD运行时却不会弹出吗?或者跟Office的安装组件也有关系,以后有机会再考虑吧。

遗留思考

WebService协议变更,即由http形式变为https形式,准确的说是禁用了低版本的协议。否则一开始是https高级协议的话,VS2005开发环境都无法直接添加引用,也无法将相关的命名空间引用的到程序。也就是说开始时,https中还允许使用SSL等低级协议,VS2005也能添加到引用,保证了相关dll可以编译,后面https禁用了SSL协议,使得当前的编译需要在更高版本的.NetFramework中运行。

所以我们可以直接切换运行环境,由WinSer2003到WinSer2012,而不是说必须要重新在VS2010等高版本VS中重新编译。就是这种所谓偷懒的切换方式吧,简单的调整了一些生成参数,然后直接切换到WinSer2012运行环境,却出现了上述描述的有些矛盾的情况。

关于问题的排查考虑了很多方面,比如跟这种切换方式、跟运行时采用的.Net框架、.CLR版本是否都有关系。就像确实是MessageBox.Show()所引起的,且跟任务计划这种调用方式有关,那为什么最开始WinSer2003可以执行的时候,通过任务计划调用却没有问题?变了的https协议影响、变了的.NetFramework影响、CMD调用模式与任务计划调用模式之区别影响。等到最后调整了调试方式,确认问题出在Excel导出模块,可能一些开始的想法被推翻,一些新的想法被验证,总之还是有不少收获,即使不能说彻彻底底明白,也算对问题有了一个交代。

断断续续排查测试,花了一两天的时间,有几个节点是本打算中止的,有时解决问题确实要看精力和时间是否足够,彻底搞清楚一件事也要看机会与缘分~@-@

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值