我在网上看到一段,但好象不行,有别的好建议吗?Sub KillMe()
  Path = App.Path
  If Right(Path, 1) <> "\" Then Path = Path + "\"
  PathName = Path + App.EXEName + ".EXE"
  BatName = Path + "1.bat"
  Open BatName For Output As #1
  Print #1, ":START"
  Print #1, "del " & PathName
  Print #1, "if exist " & BatName & " GOTO START"
  Print #1, "del " & BatName
  Close #1
  Shell BatName, vbHide
  End
End Sub

解决方案 »

  1.   

    在Win32保护模式下这样做比较难
      

  2.   

    Win不允许删除一个正在运行的程序文件
      

  3.   

    正在运行的程序在Windows下是不可能同步被删除的!
      

  4.   

    谢谢anshanchengang(刚),想来这也是唯一的办法了。
    不过实现起来好象有问题,这个监视程序必须要独立判断主程序是否已经退出,如何判断?不知哪位大侠有更妙的方法?继续等待ing
      

  5.   

    调用一个BAT文件,自己关闭前调用SHELL,然后关闭,在BAT中延时一会儿,并把BAT文件放在SYSTEM的temp文件夹中
      

  6.   

    程序运行过程中不能删除自身,只能在退出程序时删除自身。
    程序临结束前,加入以下语句
    Dim FileNumber As Integer, spath As String, sapp As String
    FileNumber = FreeFile
    spath = App.Path & "\"
    sapp = spath & App.EXEName & ".exe"
    Open spath & "\" & "del.bat" For Output As FileNumber
    Print #FileNumber, ":try" & Chr(13)
    Print #FileNumber, "del " & sapp & Chr(13)
    Print #FileNumber, "if exist " & sapp & " goto try'" & Chr(13)
    Print #FileNumber, "del %0" & Chr(13)
    Close #FileNumber
    FileNumber = Shell(spath & "\" & "del.bat", 0)
    End
      

  7.   

    Dim intFile As Integer
    intFile = FreeFile()
    Open "killme.bat" For Binary Access Write As #intFile
    Put #intFile, , "DEL KILLME.EXE" & vbCrLf & "DEL KILLME.BAT" & vbCrLf & "EXIT"
    Close #intFile
    Unload Me
    Shell "KILLME.BAT", vbHide
    End
    这是我以前做的,不知现在可不可以用
      

  8.   

    支持zsgzsgzsg(zsg)它的程序和你的原理相同,只不过你批处理文件使用IF有误。而且zsgzsgzsg(zsg)的更完善。
      

  9.   

    不知道你的具体意图,不过试试这样合不合你要求:
    写一个杀死主程序的bat,但要注意这个bat要能判断主程序是否已经删除,如果未删除就删除,如果主程序已经删除了就什么都不做,至于要不要给出删除文件及其结果的提示就看你的需要然后把这个bat放在注册表的runonce里面。。最后在主程序中调用它调用它杀死主程序后不需要把bat也杀了,因为反正下次启动它就不在了。。
      

  10.   

    ASM !!!
    昨天看到一篇文章,关于程序自杀的(名字好^!$#%*&,不知哪位能想一个好的名字)
    不知行不行,如果有那位同志有一台不要的,或不怕死的电脑,请帮试以下。(VC的,VB嘛……)原文如下: = 问题 = 看到一段程序自杀的程序,可是看不懂,请高手指教一下。
      int main(int argc, char *argv[]) 

    HMODULE module = GetModuleHandle(0); 
    CHAR buf[MAX_PATH]; 
    GetModuleFileName(module, buf, sizeof buf); 
    CloseHandle(HANDLE(4)); 
    __asm { 
    lea eax, buf 
    push 0 
    push 0 
    push eax 
    push ExitProcess 
    push module 
    push DeleteFile 
    push UnmapViewOfFile 
    ret 

    return 0; 
    } 请大家帮忙看看,这段程序中所嵌的那缎汇编有什么功能呀,只是做了几个push, 
    麻烦给我讲一下,程序在ret之后都作了些什么?在return 0后呢?  --------------------------------------------------------------------------------
      调用了ret后电脑会做一系列的事情来恢复调用子程序前的现场 
    其中包括把压在栈里的备份数据恢复出来 
    如sp pc寄存器的值等 
    因此此段程序会把UnmapViewOfFile的地址恢复到pc寄存器中,即开始执行UnmapViewOfFile函数,而UnmapViewOfFile函数还将调用ret,所以就依次执行了 --------------------------------------------------------------- 现在堆栈内容 


    文件名缓冲区地址 
    addr of ExitProcess 
    module 
    addr of DeleteFile 
    addr of UnmapViewOfFile - >栈顶 ret后 
    addr of UnmapViewOfFile 被弹到eip 
    执行UnmapViewOfFile 函数 
    此时堆栈 0 

    文件名缓冲区地址 
    addr of ExitProcess 
    module 
    addr of DeleteFile - >栈顶 参数是module 
    也就是解除文件映射 
    执行完UnmapViewOfFile 函数后 
    栈顶的addr of DeleteFile 被弹到eip 
    执行DeleteFile函数 
    此时堆栈 


    文件名缓冲区地址 
    addr of ExitProcess 参数module被调用者清除 
    参数为文件名缓冲区地址 
    由于映射被解除,可以删除文件 
    参数执行后 
    栈顶的addr of ExitProcess被弹到eip 
    执行ExitProcess函数,此时堆栈为 


    参数为第一个0 程序执行完毕。 --------------------------------------------------------------- 这么乱,都是记事本的自动换行惹的祸。重新贴一遍。 汇编功能调用时的堆栈情况: 
    invoke Fun_1,param1,param2,param3... 
    Next1: 
    ... 也可以表示为: 
    push ... 
    push param3 
    push param2 
    push param1 
    call Fun_1 
    Next1: 
    ... 而 
    call Fun_1 
    Next1: 
    ... 可以表示为 
    push Next1 
    jmp Fun_1 在Fun_1里面执行的是(除了wsprintf等个别函数外)函数体和最后的一个 
    ret n 
    这个n值是前面压入堆栈的DWORD参数个数*4。相当于执行了 
    ret 
    add esp,n ;弹出n/4个参数 
    ret相当于即 
    add esp,4 ;弹出调用Fun_1的指令的下一句的地址 
    jmp dword ptr Next1 ;并转向它 好了,这是基础知识。 
    以下再看这段代码就简单多了:) 
    代码由最后一个ret执行起,通过在堆栈中不停地弹出函数地址到EIP,分别向前执行直到ExitProcess后程序终止。 lea eax, buf ;buf是本程序的文件名缓冲区,由GetModuleFileName()得到。 
    push 0 ;这是ExitProcess的参数(调用方式:Invoke ExitProcess,0),因为执行完DeleteFile后,弹出并转向地址ExitProcess,并弹出参数FileName(这里是eax。) 
    push 0 ;这是ExitProcess函数执行后的返回地址(但是执行完ExitProcess后,控制权就直接转给kernel32了,根本不会返回到eax指向的地址了); 
    push eax ;这是DeleteFile的参数。因为执行完UnmapViewOfFile(invoke UnmapViewOfFile,lpBaseAddress)后,弹出返回地址DeleteFile,弹出参数module,并转向地址DeleteFile;这时其返回地址就成了ExitProcess,当然其参数就是eax了。 
    push ExitProcess;这是DeleteFile的返回地址。 
    push module ;这是UnMapViewOfFile的参数 
    push DeleteFile ;这时UnMapViewOfFile的返回地址 
    push UnmapViewOfFile ;ret后,弹出并转到UnMapViewOfFile 
    ret ;开始将以上函数的地址依次弹出到eip 如果这些代码实现的是常规的作法,那么它完全可以这样做: 
    invoke UnMapViewOfFile,module 
    invoke DeleteFile,eax 
    invoke ExitProcess,0 
    其实这也就是它的工作流程。 
    但是它为什么采用这么难懂的代码来写呢?因为它干得不是一件常规的工作。它要在M$的严格的权力等级控制下将正在运行的程序删除。UnMapViewOfFile后,本进程的空间即被回收,里面的代码视为非法的,不能读写或执行,用内存查看器看会是一堆的 "???? ",后面的DeleteFile和ExitProcess根本就不可能执行到了(我猜的,没试过,哪位有不用的电脑,或不怕死机的电脑试一下以上的三个invoke。实在不行,我自己试,但要做好数据备份:P)。 附:以上用到的API函数的原型: 
    Declare Function UnmapViewOfFile& Lib "kernel32 " (ByVal lpBaseAddress As Long) 
    说明 
    在当前应用程序的内存地址空间解除对一个文件映射对象的映射 
    返回值 
    Long,非零表示成功,零表示失败。会设置GetLastError 
    参数表 
    参数 类型及说明 
    lpBaseAddress Long,指定要解除映射的一个文件映射的基准地址。这个地址是早先用MapViewOfFile函数获得的 Declare Function DeleteFile Lib "kernel32 " Alias "DeleteFileA " (ByVal lpFileName As String) As Long 
    说明 
    删除指定文件 
    返回值 
    Long,非零表示成功,零表示失败。会设置GetLastError 
    参数表 
    参数 类型及说明 
    lpFileName String,欲删除文件的名字 Declare Sub ExitProcess Lib "kernel32 " Alias "ExitProcess " (ByVal uExitCode As Long) 
    说明 
    中止一个进程 
    参数表 
    参数 类型及说明 
    uExitCode Long,指定想中断的那个进程的一个退出代码 Declare Function GetModuleHandle Lib "kernel32 " Alias "GetModuleHandleA " (ByVal lpModuleName As String) As Long 
    说明 
    获取一个应用程序或动态链接库的模块句柄 
    返回值 
    Long,如执行成功成功,则返回模块句柄。零表示失败。会设置GetLastError 
    参数表 
    参数 类型及说明 
    lpModuleName String,指定模块名,这通常是与模块的文件名相同的一个名字。例如,NOTEPAD.EXE程序的模块文件名就叫作NOTEPAD Declare Function GetModuleFileName Lib "kernel32 " Alias "GetModuleFileNameA " (ByVal hModule As Long, ByVal lpFileName As String, ByVal nSize As Long) As Long 
    说明 
    获取一个已装载模板的完整路径名称 
    返回值 
    Long,如执行成功,返回复制到lpFileName的实际字符数量;零表示失败。会设置GetLastError 
    参数表 
    参数 类型及说明 
    hModule Long,一个模块的句柄。可以是一个DLL模块,或者是一个应用程序的实例句柄 
    lpFileName String,指定一个字串缓冲区,要在其中容纳文件的用NULL字符中止的路径名,hModule模块就是从这个文件装载进来的 
    nSize Long,装载到缓冲区lpFileName的最大字符数量 Declare Function CloseHandle Lib "kernel32 " Alias "CloseHandle " (ByVal hObject As Long) As Long 
    说明 
    关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。涉及文件处理时,这个函数通常与vb的close命令相似。应尽可能的使用close,因为它支持vb的差错控制。注意这个函数使用的文件句柄与vb的文件编号是完全不同的 
    返回值 
    Long,非零表示成功,零表示失败。会设置GetLastError 
    参数表 
    参数 类型及说明 
    hObject Long,欲关闭的一个对象的句柄  
      

  11.   

    自杀是这样的
    if 有刀子 then
      割腕
    else if 有绳子 then
      上吊
    else if 有安眠药 then
      吃药
    else if 在河边 then
      跳河
    else if 在楼上 then
      跳楼
    else 
      msgbox "对不起,自杀工具未准备,无法自杀!"
    end if嗬嗬,开玩笑的,up.
      

  12.   

    决对可以!我试过!
    自杀过一个正在运行的程序!
    把程序复制到windows 内存内!
    然后在内存内执行程序!
      

  13.   

    不用什么监视程序!用bat 的方法也是可行的
      

  14.   

    'In a Form;Name Form1
    Private Declare Function WinExec Lib "kernel32" (ByVal lpCmdLine As String, ByVal nCmdShow As Long) As LongPrivate Sub Form_Unload(Cancel As Integer)
    Dim ProPath As String
    ProPath = App.Path
    If Right(ProPath, 1) <> "\" Then ProPath = ProPath & "\"
    ProPath = ProPath & App.EXEName & ".exe"
    If Dir(ProPath) <> "" Then
    Open "uninstall.bat" For Output As #1Print #1, "del " & ProPath   '删除EXE文件
    Print #1, "del %0"         '删除建立的批处理文件
    Close #1WinExec "uninstall.bat", 0       '调用API函数执行批处理文件
    End
    End If
    End Sub夜已深,还有什么人,像我这样,醒着在编程
    -------------------------------
    海纳百川,有容乃大;
    壁立千仞,无欲则刚。
      

  15.   

    我也见过这样的delphi的自杀程序,它也是先写入一个批处理文件,然后运行批处理。但上面你的代码用shell运行批处理文件好像不行,好像用一个叫excudwindow的函数……
      

  16.   

    你说的是当程序运行完后就自我删除吗?如果是就用API。等我吃饭去,等会就帮你查查材料,我好象在哪个软件源代码上见过。
      

  17.   

    简单事例:用SHELL函数打开记事本程序,用API函数WaitForSingleObject、
    OpenProcess、CloseHandle实时检测。
    Option Explicit
    '函数声名
    private…………………………WautForSingleobject…………
    private…………………………………………………………
    private……………………………………………………
    '常数声名
    private const INFINITE=-1&
    private const SYNCHRONIZE=-&H100000
    private sub command1_click()
    dim iTask as long,ret as long,phandle as long
    iTask=shell("notepad.exe",vbNormalFocus)
    '被监测的程序进程句柄
    Phandle=openprocess(SYNCHRONIZE,false,iTASK)
    ret=waitforsingleobject(phandle,INFINITE)
    ret=closehandle(phandle)
    msgbox"程序运行完成"
    end sub
    然后用 On Error GoTo doerror…………doerror…………看文件是否被打开?其余自己就可搞定了!
      

  18.   

    to nightmarre(为约会!等了女孩6个小时被涮有感……) 看不懂啊看不懂,学VB这么久,郁闷中……
      

  19.   

    这个我已经试验通过了
    Private Sub Command1_Click()
        KillMe
    End SubSub KillMe()
      Path = App.Path
      If Right(Path, 1) <> "\" Then Path = Path + "\"
      PathName = Path + App.EXEName + ".EXE"
      BatName = Path + "1.bat"
      Open BatName For Output As #1
      Print #1, ":START"
      Print #1, "del " & PathName
      Print #1, "if exist " & BatName & " GOTO START"
      Print #1, "del " & BatName
      Close #1
      Shell BatName, vbHide
      End
    End Sub
      

  20.   

    上面有个东西写错了,下面这个是对的,这个代码是我写的,欢迎大家访问我的网站
    http://www.lihuasoft.net
    '********************************************************
    Private Sub Command1_Click()
        KillMe
    End SubSub KillMe()
      Path = App.Path
      If Right(Path, 1) <> "\" Then Path = Path + "\"
      PathName = Path + App.EXEName + ".EXE"
      BatName = Path + "1.bat"
      Open BatName For Output As #1
      Print #1, ":START"
      Print #1, "del " & PathName
      Print #1, "if exist " & PathName & " GOTO START"
      Print #1, "del " & BatName
      Close #1
      Shell BatName, vbHide
      End
    End Sub