为了实现软件的自动升级,我是这样做的:
程序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没有被释放不允许被覆盖),我不得其解,请高手指点谜津!

解决方案 »

  1.   

    程序没有被卸载,
    Unload Me这一句放在最后最好换成End
      

  2.   

    估计是fso对象没有被释放的问题复制文件建议使用vb提供的FileCopy函数,即
    程序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
      

  3.   

    程序没有被卸载,
    Unload Me这一句放在最后最好换成End没看清楚,原程序已有End同意楼上 :D
      

  4.   

    B启动时可带参数,例如
    dim l as long
    l = GetCurrentProcess()
    b.exe l在B中检查这个进程是否存在,如果存在结束该进程(A进程)
    TerminateProcess
      

  5.   


    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,进程的一个退出代码
      

  6.   

    程序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
    -------------------------------------------------上面的这段代码是在那里执行的?如果是在form_load()里执行是要出问题的,因为在A还没卸载完全的情况下要覆盖A是不行的,建议使用API函数findwindow()在B里查找A,找到后再用CloseHandle()关闭A、然后用普通的VB内建函数备份、删除、重建A
      

  7.   

    谢谢各位的热心帮忙! to qiqunet(暗黑神话),rainstormmaster(rainstormmaster):你们的方法我已试过,还是不行,A进程没有关闭,拒绝A。EXE的重建。
    to  daviddivad(你真行,居然比我还快! Scorpio):
      你的方法我不会用,能给个详细的过程吗?
     另:还有其它的方法实现我需要的这个功能吗?
      

  8.   

    to seakingx(抗日统一联盟:亚龙湾) :
    延时我已试过,不行。
    我想这个问题应该理解为:子进程(B)如何关闭父进程(A)。望各位帮助!
      

  9.   

    程序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
      

  10.   

    to  rainstormmaster(rainstormmaster):
     去掉 unload me 后,A关闭时提示非法操作,跳过后,还是“拒绝的权限”不能重建A
    不知何故?
      

  11.   

    '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
      

  12.   

    qiqunet(暗黑神话) :
    用你的办法还是不行,不能关闭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
      

  13.   

    没理由,我调试通过了的,看了你的回复我又将上面的程序调试过了一遍,还是没问题'注意,A的form的caption值应为“A.exe”,而B的form的caption值不能为“A.exe”
    '问题出在用shell函数时,B是A的子进程,B不能删除A,问题出在A
    '我用的是两个工程,而不是两个线程
      

  14.   

    qiqunet(暗黑神话) :
    你是编译后调试的吗?
    严格按照:
        A的form的caption值应为“A.exe”,而B的form的caption值不能为“A.exe”
        我将两个程序分别编译后,执行还是不行。我的环境是win98+vb6.0
    我发现运行A后,再运行B,A竟然没有被关闭?
      

  15.   

    我用的是winXP + VB5
    不知是不是同开发环境有关
    但在上述环境中A用shell函数打开B,B的执行是失败的
    但改成API函数ShellExecute()就成功了
    你再自己调试一下吧,留意一下Findwindow()函数是否找到了A.exe,CloseHandle()函数是否将A.exe关闭了(可通过查询它们的返回值知道结果)。
    我也没有什么办法了,帮忙也只能帮到这了。
      

  16.   


    我们的开发环境很有趣,呵呵
    win98+vb6.0
    winXP+VB5
      

  17.   

    qiqunet(暗黑神话):
    谢谢!CloseHandle() 和 SendMessage()都关闭不了A。EXE 不知何故?
    再次感谢你的支持!谢谢你!祝你好运!
      

  18.   

    CloseHandle() 函数的局限:除非对内核对象的所有引用都已关闭,否则该对象不会实际删除
      

  19.   

    findwindow()好象是查找顶级窗体的,更换这一句看看?
    aa = FindWindow(0, "A.exe")
    换为
    aa = FindWindow("ThunderRT5Main", "工程1")
      

  20.   

    谢谢各位的支持!问题我已解决!方法如下`:
    '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