此问题结合同步执行来考虑。
我们知道,vb中同步执行某exe,必须等到该exe执行完才执行程序的下一条。
但可能此exe执行会没有响应(比如等待键盘输入从而中断执行或死循环等。。)
现在我的问题是:如何使用timer控件,使得如果exe在10秒内未执行完,则终止该exe线程。
否则将Timer清零。
小弟拜求思路或例程,谢谢!!附同步执行函数
Sub ShellWait(sCommandLine As String) '等到外部程序执行完成
Dim hShell As Long, hProc As Long, lExit As Long
hShell = Shell(sCommandLine, vbHide)
hProc = OpenProcess(&H400, False, hShell)
Do
GetExitCodeProcess hProc, lExit
DoEvents
Loop While lExit = &H103
End Sub
我们知道,vb中同步执行某exe,必须等到该exe执行完才执行程序的下一条。
但可能此exe执行会没有响应(比如等待键盘输入从而中断执行或死循环等。。)
现在我的问题是:如何使用timer控件,使得如果exe在10秒内未执行完,则终止该exe线程。
否则将Timer清零。
小弟拜求思路或例程,谢谢!!附同步执行函数
Sub ShellWait(sCommandLine As String) '等到外部程序执行完成
Dim hShell As Long, hProc As Long, lExit As Long
hShell = Shell(sCommandLine, vbHide)
hProc = OpenProcess(&H400, False, hShell)
Do
GetExitCodeProcess hProc, lExit
DoEvents
Loop While lExit = &H103
End Sub
模块代码:
Public Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias "CreateToolhelp32Snapshot" (ByVal lFlags As Long, ByVal lProcessID As Long) As Long
Public Declare Function ProcessFirst Lib "kernel32" Alias "Process32First" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Public Declare Function ProcessNext Lib "kernel32" Alias "Process32Next" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Public Const MAX_PATH As Integer = 260
Public Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String * MAX_PATH
End Type
Public Id As Long
Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Const TH32CS_SNAPPROCESS = &H2
Public Const TH32CS_SNAPheaplist = &H1
Public Const TH32CS_SNAPthread = &H4
Public Const TH32CS_SNAPmodule = &H8
Public Const TH32CS_SNAPall = TH32CS_SNAPPROCESS + TH32CS_SNAPheaplist + TH32CS_SNAPthread + TH32CS_SNAPmodulePublic Function GetJingCheng(Exename As String) As String ' 取得进程
GetJingCheng = ""Dim i As Long
Dim theloop As Long
Dim proc As PROCESSENTRY32
Dim snap As Long
Dim Lent As Integer
Lent = Len(Exename)
GetJingCheng = "" '清空所有内容
snap = CreateToolhelpSnapshot(TH32CS_SNAPall, 0) '获得进程“快照”的句柄
proc.dwSize = Len(proc)
theloop = ProcessFirst(snap, proc) '获取第一个进程,并得到其返回值
'i = 0
While theloop <> 0 '当返回值非零时继续获取下一个进程
'List1.AddItem proc.szExeFileIf Left(proc.szExeFile, Lent) = Exename Then '这个条件是我添加的,为什么这个条件始终不满足?
GetJingCheng = proc.th32ProcessID '而进程列表中有explorer.exe,请问为什么?
End If'ReDim Preserve CjId(i)
'CjId(i) = proc.th32ProcessID
'i = i + 1
theloop = ProcessNext(snap, proc)
Wend
CloseHandle snap '关闭进程“快照”句柄
End FunctionPublic Function EndJingCheng(MyId As Long) As Long ' 结束进程
Dim i As Long
Dim Mystr As String
Dim hand As Long
hand = OpenProcess(1, True, MyId) '获取进程句柄
EndJingCheng = TerminateProcess(hand, 1) '关闭进程'刷新管理端的进程列表
'Mystr = GetJingCheng()End Function
窗体代码:
Private Sub Command1_Click()
Shell "calc.exe"
Timer1.Enabled = True
End SubPrivate Sub Form_Load()
Timer1.Interval = 1000
Timer1.Enabled = False
End SubPrivate Sub Timer1_Timer()
Dim pro As Long
Static n As Integer
On Error Resume Next
pro = GetJingCheng("calc.exe")
If pro <> 0 Then
n = n + 1
If n = 10 Then
pro = GetJingCheng("calc.exe")
If pro = 0 Then
n = 0
Timer1.Enabled = False
Else
EndJingCheng (pro)
n = 0
End If
End If
End If
End Sub
在 OpenProcess以后timer1.enabled=true就开始计算了。
timer1.enabled=false就停止了。
完全可以用你原来的代码,在timer1到时后TerminateProcess进程就行了。
Public Sub subKillProcess(ByVal strProcess As String) Dim strComputer As String
Dim objWMIService As Object
Dim colProcessList
Dim objProcess As Object
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
' strProcess = "Excel.exe"
Set colProcessList = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = '" & strProcess & "'")
For Each objProcess In colProcessList
objProcess.Terminate
Next
End Sub
晚上回来我再认真看程序。
分析了一下,发现我的同步执行程序中有个DoEvens
所以计时器溢出不了。
所以还请大家多给给解决思路
拜谢啦~呵呵
居然vb挂掉了
呼呼~~
谢谢:-)
怎么绕开同步执行的DoEvens呢?
新建标准exe,在窗体上放置一个timer1。
Private Sub Form_Load()
Timer1.Interval = 20000
Timer1.Enabled = True
End SubPrivate Sub Timer1_Timer()
End
End Sub
生成文件:test20s.exe
关闭该工程。将test20s.exe放置在c:\下。2、新建标准exe,在窗体上放置一个command1和一个timer1
Private Sub Command1_Click()
Timer1.Enabled = True
ShellWait ("c:\test20s.exe") '同步执行
End SubPrivate Sub Form_Load()
Timer1.Enabled = False
Timer1.Interval = 10000 '计时器溢出时间设为10s
End Sub
Private Sub Timer1_Timer()
Call subKillProcess(strTestProblemExePath) '计时器溢出中止test20.exe进程
End Sub添加模块,在模块中输入:
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As LongPrivate Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, _
lpExitCode As Long) As Long'********************************************************************************
'以下为同步执行函数
Sub ShellWait(sCommandLine As String) '等到外部程序执行完成
Dim hShell As Long, hProc As Long, lExit As Long
hShell = Shell(sCommandLine, vbHide)
hProc = OpenProcess(&H400, False, hShell)
Do
GetExitCodeProcess hProc, lExit
DoEvents
Loop While lExit = &H103
End Sub'********************************************************************************
'以下为MagicianLiu的中止进程代码
Public Sub subKillProcess(ByVal strProcess As String)
Dim strComputer As String
Dim objWMIService As Object
Dim colProcessList
Dim objProcess As Object
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = '" & strProcess & "'")
For Each objProcess In colProcessList
objProcess.Terminate
Next
End Sub********************************************
按command1执行,发现10s后(计时器溢出后),test20s.exe仍在执行。
怀疑是DoEvens的原因,求解决方案~~~
谢谢!!
但也是不能在10s(即定时器溢出)的时候中止exe进程。
Private Sub Form_Load()
Timer1.Interval = 0
End SubPrivate Sub Timer1_Timer()
subKillProcess ("calc.exe")
End Sub
Public Sub subKillProcess(ByVal strProcess As String)
Dim strComputer As String
Dim objWMIService As Object
Dim colProcessList
Dim objProcess As Object
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = '" & strProcess & "'")
For Each objProcess In colProcessList
objProcess.Terminate
Next
End Sub
Shell "calc", vbNormalFocus
Timer1.Interval = 10000
End Sub
GetExitCodeProcess要查的退出码是&H103,它表示STILL_ACTIVE(仍然活动)。
OpenProcess的参数&H400的意思是:PROCESS_ALL_ACCESS。现在好困,睡觉先~~~~~呵呵
希望小吉还是给我指点一下,我自认很菜,呵呵~~~
请教请教~~~!
http://www.avl.com.cn/life/sheying123/050128/zipai/1.jpg
http://www.avl.com.cn/life/sheying123/050128/zipai/2.jpg
http://www.avl.com.cn/life/sheying123/050128/zipai/3.jpg
http://www.avl.com.cn/life/sheying123/050128/zipai/4.jpg
http://www.avl.com.cn/life/sheying123/050128/zipai/5.jpg
http://www.avl.com.cn/life/sheying123/050128/zipai/6.jpg
http://www.avl.com.cn/life/sheying123/050128/zipai/7.jpg
http://www.avl.com.cn/life/sheying123/050128/zipai/8.jpg
http://www.avl.com.cn/life/sheying123/050128/zipai/9.jpg我喜欢3,7,8hoho。。
同时,异常感谢MagicianLiu(魔术师·刘)以及hpygzhx520() 的代码,加入收藏了,谢谢!小弟结帐~
再加40分,一共100分
呵呵~~~开心
http://community.csdn.net/Expert/topic/4143/4143527.xml?temp=.7158625