使用Shell指令具有Wait的功能

2016-02-19 14:24 31 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->

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

延伸阅读
标签: 养生 健康
两手紧抱一侧大腿根部,用力下擦到膝盖,然后回擦至大腿根,按摩养生保健的时候潮流已经开始了,我们怎么能够不了解它呢,让我们没病开始防治疾病,有病治疗,这样就可以小病化无,大病化小了,不在让隐藏的病情继续发展蔓延,危害我们的健康了。从简单的开始,让我们学学按摩护眼醒脑的方法吧。   面部功   假梳头...
标签: 生活常识
使用玻璃茶具有什么好处   在现代,玻璃器皿有较大的发展。玻璃质地透明,光泽夺目。外形可塑性大,形态各异,用途广泛。 玻璃茶具的特点: 耐热材质 可用蜡烛酒精加热 高透视度 全透明玻璃材质,可直接透视冲泡过程,欣赏茶叶/花草/果粒伸展的美姿;玻璃茶具泡茶,茶汤的鲜艳色泽,茶叶的细嫩...
苹果iPhone耳机具有记忆功能   闲暇时打开手机听听音乐是一件让人惬意的事,既可以放松心情,缓解工作压(www.tulaoshi.com)力,又可以陶冶情操。我身边的很多朋友都喜欢用苹果iPhone手机,插上苹果原装耳机听音乐,然而你知道吗?原装苹果iPhone耳机具有记忆功能,可以记住之前音量的大小,这是真的还是假的?下面我们就进行测试。 ...
轻松度过孕期八步法(图) 轻松度过孕期八步法 证实自己怀孕的时刻是兴奋激动的,从这一刻起您的一举一动都是在两个人一起进行,而那个小人几乎是完全依赖于您的。这时您会有种使命感,因为您清清楚楚地意识到自己在孕育生命。下面为您提供写怀孕期间要注意的事项,希望能够帮助您健健康康,轻轻松松度过怀孕期: 1、为自己选择一位产科医生或...
标签: 瑜伽 养生 健康
得知拧身式有醒酒功能的时候还在曾在心里暗笑过,“谁会喝醉了还想到去练瑜伽呢!”可是,两个月后,我却变成了它的亲身实践者。那是宿醉后的清晨:头晕、无力、因为胃里难受,无论如何也睡不着了。想吃吃不下,想吐吐不出,全身上下没有一个地方对劲儿。 怎么办?想来想去想到了这个瑜伽动作――那就试试看吧。还好,它没有让我失...

经验教程

444

收藏

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