为了实现软件的自动升级,我是这样做的:
程序A中:
Unload Me
If right(App.path, 1) <> "\" Then
Shell (App.path & "\" & "B.exe") '启动b.exe
Else
Shell (App.path & "B.exe")
End If
End '关闭A.exe
程序B中:
Dim FS
Set FS = CreateObject("Scripting.FileSystemObject")
FS.copyfile App.Path & "\A.exe", App.Path & "\A.bak" '备份A.exe
Kill App.Path & "\A.exe
FS.copyfile App.Path & "\C.exe", App.Path & "\A.exe" '用新文件c.exe替换A.exe
Kill App.Path & "\C.exe"
Shell App.Path & "\A.exe" '启动A.exe
End '关闭b.exe以上代码程序A中可以顺利执行,程序B中会出现错误(A没有被释放不允许被覆盖),我不得其解,请高手指点谜津!
程序A中:
Unload Me
If right(App.path, 1) <> "\" Then
Shell (App.path & "\" & "B.exe") '启动b.exe
Else
Shell (App.path & "B.exe")
End If
End '关闭A.exe
程序B中:
Dim FS
Set FS = CreateObject("Scripting.FileSystemObject")
FS.copyfile App.Path & "\A.exe", App.Path & "\A.bak" '备份A.exe
Kill App.Path & "\A.exe
FS.copyfile App.Path & "\C.exe", App.Path & "\A.exe" '用新文件c.exe替换A.exe
Kill App.Path & "\C.exe"
Shell App.Path & "\A.exe" '启动A.exe
End '关闭b.exe以上代码程序A中可以顺利执行,程序B中会出现错误(A没有被释放不允许被覆盖),我不得其解,请高手指点谜津!
Unload Me这一句放在最后最好换成End
程序B中:
FileCopy App.Path & "\A.exe", App.Path & "\A.bak" '备份A.exe
Kill App.Path & "\A.exe
FileCopyApp.Path & "\C.exe", App.Path & "\A.exe" '用新文件c.exe替换A.exe
Kill App.Path & "\C.exe"
Shell App.Path & "\A.exe" '启动A.exe
End '关闭b.exe
Unload Me这一句放在最后最好换成End没看清楚,原程序已有End同意楼上 :D
dim l as long
l = GetCurrentProcess()
b.exe l在B中检查这个进程是否存在,如果存在结束该进程(A进程)
TerminateProcess
TerminateProcess(l,byval 0&)
l为原先传入的值【VB声明】
Private Declare Function TerminateProcess Lib "kernel32" Alias "TerminateProcess" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long【说明】
结束一个进程
在VB里使用
可以使用,但尽量不用 【返回值】
Long,非零表示成功,零表示失败。会设置GetLastError 【参数表】
hProcess ------- Long,指定要中断的一个进程的句柄 uExitCode ------ Long,进程的一个退出代码
Dim FS
Set FS = CreateObject("Scripting.FileSystemObject")
FS.copyfile App.Path & "\A.exe", App.Path & "\A.bak" '备份A.exe
Kill App.Path & "\A.exe
FS.copyfile App.Path & "\C.exe", App.Path & "\A.exe" '用新文件c.exe替换A.exe
Kill App.Path & "\C.exe"
Shell App.Path & "\A.exe" '启动A.exe
End '关闭b.exe
-------------------------------------------------上面的这段代码是在那里执行的?如果是在form_load()里执行是要出问题的,因为在A还没卸载完全的情况下要覆盖A是不行的,建议使用API函数findwindow()在B里查找A,找到后再用CloseHandle()关闭A、然后用普通的VB内建函数备份、删除、重建A
to daviddivad(你真行,居然比我还快! Scorpio):
你的方法我不会用,能给个详细的过程吗?
另:还有其它的方法实现我需要的这个功能吗?
延时我已试过,不行。
我想这个问题应该理解为:子进程(B)如何关闭父进程(A)。望各位帮助!
'Unload Me 这句去了吗
If right(App.path, 1) <> "\" Then
Shell (App.path & "\" & "B.exe") '启动b.exe
Else
Shell (App.path & "B.exe")
End If
End '关闭A.exe
去掉 unload me 后,A关闭时提示非法操作,跳过后,还是“拒绝的权限”不能重建A
不知何故?
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPrivate Sub Form_Unload(Cancel As Integer)
filename = App.Path & "\B.exe"
ShellExecute 0, vbNullString, filename, "", "", vbNormalFocus
End
End Sub
'B的程序代码:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As LongPrivate Sub Form_Load()
Dim aa As Long
aa = FindWindow(0, "A.exe")
CloseHandle aa
ChDir App.Path
FileCopy "A.exe", "A.bak"
Kill "A.exe"
FileCopy "c.exe", "A.exe"
End Sub'注意,A的form的caption值应为“A.exe”,而B的form的caption值不能为“A.exe”
'问题出在用shell函数时,B是A的子进程,B不能删除A
用你的办法还是不行,不能关闭A进程。
Private Sub Form_Load()
Dim aa As Long
aa = FindWindow(0, "A.exe")
CloseHandle aa
ChDir App.Path
FileCopy "A.exe", "A.bak"
Kill "A.exe" ’-------------------出错:文件访问错误
FileCopy "c.exe", "A.exe"
End Sub
'问题出在用shell函数时,B是A的子进程,B不能删除A,问题出在A
'我用的是两个工程,而不是两个线程
你是编译后调试的吗?
严格按照:
A的form的caption值应为“A.exe”,而B的form的caption值不能为“A.exe”
我将两个程序分别编译后,执行还是不行。我的环境是win98+vb6.0
我发现运行A后,再运行B,A竟然没有被关闭?
不知是不是同开发环境有关
但在上述环境中A用shell函数打开B,B的执行是失败的
但改成API函数ShellExecute()就成功了
你再自己调试一下吧,留意一下Findwindow()函数是否找到了A.exe,CloseHandle()函数是否将A.exe关闭了(可通过查询它们的返回值知道结果)。
我也没有什么办法了,帮忙也只能帮到这了。
我们的开发环境很有趣,呵呵
win98+vb6.0
winXP+VB5
谢谢!CloseHandle() 和 SendMessage()都关闭不了A。EXE 不知何故?
再次感谢你的支持!谢谢你!祝你好运!
aa = FindWindow(0, "A.exe")
换为
aa = FindWindow("ThunderRT5Main", "工程1")
'b程序中:
Option Explicit
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)Sub Main()
Call EndTask(“A”)
Call Sleep(5000) '延时5秒
If Dir(App.Path & "\C.exe") <> "" Then
DoEvents
FileCopy App.Path & "\A.exe", App.Path & "\A.bak"
Kill App.Path & "\A.exe"
FileCopy App.Path & "\C.exe", App.Path & "\A.exe"
Kill App.Path & "\C.exe"
Shell App.Path & "\A.exe"
End If
End
End Sub'B模块中:
Option Explicit'API's Function Declarations
Private Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As LongPrivate Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" ( _
ByVal hwnd As Long, _
ByVal nIndex As Long) As LongPrivate Declare Function PostMessage Lib "user32" Alias "PostMessageA" ( _
ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As LongPublic Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As Any, _
ByVal lpWindowName As String) As Long'API Constants
Public Const GWL_STYLE = -16
Public Const WS_DISABLED = &H8000000
Public Const WM_CANCELMODE = &H1F
Public Const WM_CLOSE = &H10Public Function EndTask(sWindowName As String) As Integer
Dim X As Long, ReturnVal As Long, TargetHwnd As Long
'find handle of the application
TargetHwnd = FindWindow(0&, sWindowName)
If TargetHwnd = 0 Then Exit Function
If IsWindow(TargetHwnd) = False Then
GoTo EndTaskFail
Else
'close application
If Not (GetWindowLong(TargetHwnd, GWL_STYLE) And WS_DISABLED) Then
X = PostMessage(TargetHwnd, WM_CLOSE, 0, 0&)
DoEvents
End If
End If
GoTo EndTaskSucceedEndTaskFail:
ReturnVal = False
MsgBox "EndTask: cannot terminate " & sWindowName & " task"
GoTo EndTaskEndSubEndTaskSucceed:
ReturnVal = TrueEndTaskEndSub:
EndTask% = ReturnVal
End Function'A的程序代码:
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPrivate Sub Form_Unload(Cancel As Integer)
dim filename as string
filename = App.Path & "\B.exe"
ShellExecute 0, vbNullString, filename, "", "", vbNormalFocus
End
End Sub