首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 软件教学-> 办公软件
使用shell指令具有wait的功能_visualbasic教程
作者:网友供稿 点击:0
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
VB中,常以Shell指令来执行外部程式,然而它在Create该外部process後,立刻
就会回到vb的下一行程式,无法做到等待该Process结束时,才执行下一行指令,
或是说,无法得知该Process是否已结束,甚者,该Process执行到一半,又该如何
中止其执行等等,这些都不是Shell指令所能控制的,因此我们需使API的帮助来完
成。

第一个问题,如何等待shell所Create的process结束後才往後执行vb的程式。
首先要知道的是,每个Process有唯一的一个ProcessID,这是OS给定的,用来
区别每个Process,这个ProcessID(PID)主要可用来取得该Process相对应的一些
资讯,然而要对该Process的控制,却大多透过ProcessHandle(hProcess)。VB
Shell指令的传回值是PID,而非hProcess,所以我们需透过OpenProcess这个API来
取得hProcess而OpenProcess()的第一个叁数,指的是所取得的hProcess所具有的
能力,像PROCESS_QUERY_INFORMATION便是让GetExitCode()可取得hProcess所指
的process之状态,而PROCESS_TERMINATE,便是让TerminateProcess(hProcess..)
的指令能够生效,也就是说,不同叁数设定,使hProcess所具有的权限、能力有所
不同。取得hProcess後便可以使用WaitForSingleObject()来等待hProcess状态的
改变,也就是说,它会等待hProcess所指的process执行完,这个指令才结束,它
第二个叁数所指的是WaitForSingleObject()所要等待的时间(inmilliseconds)
,如果超过所指的时间,就TimeOut而结束WaitForSingleObject()的等待。若要它
无限的等下去,就设定为INFINITE。

pid=Shell("C:\tools\spe3\pe2.exe",vbNormalFocus)
hProcess=OpenProcess(PROCESS_QUERY_INFORMATION,0,pid)
ExitEvent=WaitForSingleObject(hProcess,INFINITE)
CallCloseHandle(hProcess)

上例会无限等待shell指令create之process结束後,才再做後面的vb指令。有
时觉得那会等太久,所以有第二个解决方式:等process结束时再通知vb就好,即
:设定一个公用变数(isDone),当它变成True时代表Shell所Create的Process已结
束。当Process还在执行时,GetExitCodeProcess会传&H103给其第二个叁数,直到
结束时才传另外的数值,如果程式正常结束,那Exitcode=0,否则就得看它如何
结束了。或许有人在其他地方看到loop的地方是LoopwhileExitcode<>0,那
有一点危险,如果以这程子来看,您不是用F4来离开pe2而是用右上方X的结束
doswindow那麽,会因为ExitCode的值永远不会是0,而进入无穷的回圈。

DimpidAsLong
pid=Shell("C:\tools\spe3\pe2.exe",vbNormalFocus)
hProcess=OpenProcess(PROCESS_QUERY_INFORMATION,0,pid)
isDone=False
Do
CallGetExitCodeProcess(hProcess,ExitCode)
Debug.PrintExitCode
DoEvents
LoopWhileExitCode=STILL_ALIVE
CallCloseHandle(hProcess)
isDone=True

另外,如果您的shell所Create的程式,有视窗且为立刻Focus者,可另外用以
下的方式DimpidAsLong
Dimhwnd5AsLong
pid=Shell("c:\tools\spe3\pe2.exe",vbNormalFocus)
hwnd5=GetForegroundWindow()
isDone=False
DoWhileIsWindow(hwnd5)
DoEvents
Loop
isDone=True



而如何强迫shell所Create的process结束呢,那便是
DimaaAsLong
IfhProcess<>0Then
aa=TerminateProcess(hProcess,3838)
EndIf

hProcess便是先前的例子中所取得的那个ProcessHandle,3838所指的是传给
GetExitCodeProcess()中的第二叁数,这是我们任意给的,但最好不要是0,因为
0一般是代表正常结束,当然这样设也不会有错。当然不可设&H103,以这个例子来
看,如果程式正处於以下的LOOP
Do
CallGetExitCodeProcess(hProcess,ExitCode)
Debug.PrintExitCode
DoEvents
LoopWhileExitCode=STILL_ALIVE
Debug.printExitCode

而执行了TerminateProcess(hProcess,3838)那会看到ExitCode=3838。然
而,这个方式在win95没问题,在NT中,可能您要在OpenProcess()的第一个叁数要
更改成PROCESS_QUERY_INFORMATIONOrPROCESS_TERMINATE这样才能Work。不过
良心的建议,非到最後关头,不要使用TerminateProcess(),因不正常的结束,往
往许多程式结束前所要做的事都没有做,可能造成Resource的浪费,甚者,下次再
执行某些程式时会有问题,例如:本人常使用MS-dosShellLink的方式执行一程
式,透过Comport与大电脑的联结,如果Ms-dosShellLink不正常结束,下次再
想Link时,会发现tooManyOpens,这便是一例。

另外,有人使用Shell来执行.bat档,即:
pid=Shell("c:\aa.bat",vbNormalFocus)
可是却遇上aa.bat结束了,但ms-dos的Window却仍活着,那可以用以下的方式来做
pid=Shell("c:\command.com/cc:\aa.bat",vbNormalFocus)
那是执行Command.com,而Command.com指定执行c:\aa.bat而且结束时自动Close
所有程式如下:
PrivateDeclareFunctionOpenProcessLib"kernel32"_
(ByValdwDesiredAccessAsLong,ByValbInheritHandleAsLong,_
ByValdwProcessIdAsLong)AsLong
PrivateDeclareFunctionWaitForSingleObjectLib"kernel32"_
(ByValhHandleAsLong,ByValdwMillisecondsAsLong)AsLong
PrivateDeclareFunctionCloseHandleLib"kernel32"_
(ByValhObjectAsLong)AsLong
PrivateDeclareFunctionGetExitCodeProcessLib"kernel32"_
(ByValhProcessAsLong,lpExitCodeAsLong)AsLong
PrivateDeclareFunctionTerminateProcessLib"kernel32"_
(ByValhProcessAsLong,ByValuExitCodeAsLong)AsLong
PrivateDeclareFunctionGetForegroundWindowLib"user32"()AsLong
PrivateDeclareFunctionIsWindowLib"user32"_
(ByValhwndAsLong)AsLong

ConstPROCESS_QUERY_INFORMATION=&H400
ConstSTILL_ALIVE=&H103
ConstINFINITE=&HFFFF

PrivateExitCodeAsLong
PrivatehProcessAsLong
PrivateisDoneAsLong
PrivateSubCommand1_Click()
DimpidAsLong
pid=Shell("C:\tools\spe3\pe2.exe",vbNormalFocus)
hProcess=OpenProcess(PROCESS_QUERY_INFORMATION,0,pid)
isDone=False
Do
CallGetExitCodeProcess(hProcess,ExitCode)
Debug.PrintExitCode
DoEvents
LoopWhileExitCode=STILL_ALIVE
CallCloseHandle(hProcess)
isDone=True
EndSub

PrivateSubCommand2_Click()
DimpidAsLong
DimExitEventAsLong
pid=Shell("C:\tools\spe3\pe2.exe",vbNormalFocus)
hProcess=OpenProcess(PROCESS_QUERY_INFORMATION,0,pid)
ExitEvent=WaitForSingleObject(hProcess,INFINITE)
CallCloseHandle(hProcess)
EndSub

PrivateSubCommand3_Click()
DimaaAsLong
IfhProcess<>0Then
aa=TerminateProcess(hProcess,3838)
EndIf

EndSub

PrivateSubCommand4_Click()
DimpidAsLong
Dimhwnd5AsLong
pid=Shell("c:\tools\spe3\pe2.exe",vbNormalFocus)
hwnd5=GetForegroundWindow()
isDone=False
DoWhileIsWindow(hwnd5)
DoEvents
Loop
isDone=True
EndSub

PrivateSubCommand5_Click()
DimpidAsLong
pid=Shell("c:\windows\command\xcopyc:\aa.bata:",vbHide)
pid=Shell("c:\command.com/cc:\aa.bat",vbNormalFocus)
EndSub->


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·ASP.NET2.0连接SQL Server数据库详解-.NET教程,Asp.Net开发
·在.net中轻松掌握Windows窗体间的数据交互-.NET教程,.NET Framework
·Java中的类反射机制-JSP教程,Java技巧及代码
·小技巧让pdf文件与word文档之间自由地转换
·j2ee程序员应该掌握的linux知识-JSP教程,J2EE/EJB/服务器
·通过WMI获得硬盘和CPU的物理序列号(VB.net)-.NET教程,VB.Net语言
·firfox浏览器开发人公开firfox2.0开发计划
·VB.net入门(10):补充:类~属性-.NET教程,VB.Net语言
·office2003实战秘笈之excel轻松制胜招
·C#编码规范.doc-.NET教程,C#语言
最新文章
·天涯试水网络口碑营销 邢明:希望与"关键词"媲美_站长访谈
·美梨网站长冰寒的商务之道_站长访谈
·白手起家 新网站流量快速提高之道_站长心得
·照片处理 photoshop简单制作照片柔光效果_photoshop教程
·网络百戒 ---网页外观_站长心得
·utf-8转换gb2312编码,解决统计google搜索来源关键字乱_google推广
·googleadsense作弊不是技术的较量_google推广
·google改进搜索服务 企业可在local更新资料_google推广
·rss订阅对你的网站搜索表现有好处吗?_站长心得
·15种简洁有效的网站推广方法_站长心得
相关主题
西部数码虚拟主机

友情链接
CNNIC 西部数码
万网 自助建站
虚拟主机 asp空间
域名注册 域名
域名申请 主页空间
论坛空间 网站空间
国际域名 虚拟空间
空间租用 DDOS防火墙
成都主机托管 四川主机托管
主机租用 服务器租用
网站目录 自助建站
虚拟主机 网址大全
软件下载
自助链接
虚拟主机资讯 特价虚拟主机
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论 打印  刷新     关闭