使用Shell指令具有Wait的功能

2016-02-19 14:24 38 1 收藏

给自己一点时间接受自己,爱自己,趁着下午茶的时间来学习图老师推荐的使用Shell指令具有Wait的功能,过去的都会过去,迎接崭新的开始,释放更美好的自己。

【 tulaoshi.com - 编程语言 】

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:oolsspe3pe2.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:oolsspe3pe2.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:oolsspe3pe2.exe",vbNormalFocus)
  hwnd5=GetForegroundWindow()
  isDone=False
  DoWhileIsWindow(hwnd5)
  DoEvents
  Loop
  isDone=True
  
  
  
  而如何强迫shell所Create的process结束呢,那便是
  DimaaAsLong
  IfhProcess0Then
  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:oolsspe3pe2.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:oolsspe3pe2.exe",vbNormalFocus)
  hProcess=OpenProcess(PROCESS_QUERY_INFORMATION,0,pid)
  ExitEvent=WaitForSingleObject(hProcess,INFINITE)
  CallCloseHandle(hProcess)
  EndSub
  
  PrivateSubCommand3_Click()
  DimaaAsLong
  IfhProcess0Then
  aa=TerminateProcess(hProcess,3838)
  EndIf
  
  EndSub
  
  PrivateSubCommand4_Click()
  DimpidAsLong
  Dimhwnd5AsLong
  pid=Shell("c:oolsspe3pe2.exe",vbNormalFocus)
  hwnd5=GetForegroundWindow()
  isDone=False
  DoWhileIsWindow(hwnd5)
  DoEvents
  Loop
  isDone=True
  EndSub
  
  PrivateSubCommand5_Click()
  DimpidAsLong
  'pid=Shell("c:windowscommandxcopyc:aa.bata:",vbHide)
  pid=Shell("c:command.com/cc:aa.bat",vbNormalFocus)
  EndSub->

来源:http://www.tulaoshi.com/n/20160219/1606921.html

延伸阅读
标签: 服务器
Linux最常用的Shell命令 有些人仍然会有这种愚蠢的想法,他们认为使用 Linux 就必须使用 Linux shell命令 。胡说!你可以不懂得任何 Linux命令 ,比如说ps,grep,ls等,但是你仍然可以使用很多现代的Linux桌面发行版。 Linux的系统管理员与桌面用户不一样,他们不像桌面用户一样使用Cinnamon,GNOME,Unity,或者KDE,他们所有的...
标签: 服务器
Linux Shell 通配符、元字符、转义符使用实例介绍   下面是一个实例: 代码如下: [chengmo@localhost ~/shell]$ ls a.txt b.txt c.old #2 [chengmo@localhost ~/shell]$ ls *.txt a.txt b.txt #3 [chengmo@localhost ~/shell]$ ls d*.txt ls: 无法访问 d*.txt: 没有那个文件或目录 ...
标签: 瑜伽 养生 健康
得知拧身式有醒酒功能的时候还在曾在心里暗笑过,“谁会喝醉了还想到去练瑜伽呢!”可是,两个月后,我却变成了它的亲身实践者。那是宿醉后的清晨:头晕、无力、因为胃里难受,无论如何也睡不着了。想吃吃不下,想吐吐不出,全身上下没有一个地方对劲儿。 怎么办?想来想去想到了这个瑜伽动作――那就试试看吧。还好,它没有让我失...
标签: 电脑入门
问:我买的LCD使用的是外置电源,由于接LCD电源适配器要占用一定桌面空间,连线也多了,比较麻烦,而且我这里电压不太稳定,担心对LCD有影响,请问现在市面上的ATX电源有没有可以直接为LCD提供比较稳定的12V电压? 答:现在的ATX电源有12V LCD电源接口的产品并不多,主要是一些中高端产品,它们一般是通过一根专用的LCD电源连线,将电源的LCD...
苹果iPhone耳机具有记忆功能   闲暇时打开手机听听音乐是一件让人惬意的事,既可以放松心情,缓解工作压(www.tulaoshi.com)力,又可以陶冶情操。我身边的很多朋友都喜欢用苹果iPhone手机,插上苹果原装耳机听音乐,然而你知道吗?原装苹果iPhone耳机具有记忆功能,可以记住之前音量的大小,这是真的还是假的?下面我们就进行测试。 ...

经验教程

696

收藏

93
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部