B不能活了……除非其他程序还有调用B的。但是如果B又调用了C.Dll,那C就能活。

解决方案 »

  1.   

         msdn 不是说:The TerminateProcess function is used to unconditionally cause a process to exit. Use it only in extreme circumstances. The state of global data maintained by dynamic-link libraries (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess. 
    TerminateProcess causes all threads within a process to terminate, and causes a process to exit, but DLLs attached to the process are not notified that the process is terminating.
            
      

  2.   

    如果有任何进程调用dll的话,DLL才能扎根
      

  3.   

    如果有进程C调用了DLL, DLL就能在内存中
      

  4.   

    在LoadLibrary的时候,系统要为DLL维护一个使用计数,当使用计数为零时,该DLL就从内存中卸载,否则只是从相应进程的地址空间中取消映射。
      

  5.   

      但是DLL应该是映射到进程的地址空间啊。
      

  6.   

    不是说只有所有调用了dll文件进程都结束了,Dll才会在内存中消失吗?
      

  7.   

      我怀疑dll还没有死亡........
      

  8.   

    Lu Lin
    All
    Real Tech(1)
    12 Apr 99  23:18:51
    REAL TECH(1) DEAD PROCESS DETECTION
    作者:陆麟
    欢迎盗版,请注明作者
    本文讨论一些真正的技巧上的问题.
    这次提出的是一个有关DLL的问题.问题的产生:
    当一个进程开始,所有需要的DLL会被加载.或许在PE LOADER装载后,PROCESS开始前,或
    在程序运行中.当然,被加载的DLL会收到一个DLL_PROCESS_ATTACH的消息.然后开始DLL
    的初始化.当一个进程终止,DLL会收到DLL_PROCESS_DETACH消息,然后进行部分清理操作.
    现在问题出现了.只有当进程是正常退出时DLL才会收到DLL_PROCESS_DETACH消息.当一
    个进程进入死循环.被用户在TASK MANAGER里终止时,DLL根本就没机会收到
    DLL_PROCESS_DETACH消息.那么就意味着DLL无法进行扫尾工作.错误的解决方法:
    有个程序员尝试在DLL里加入一段代码.用WaitSingalObject(hprocess,INFINITY)来监
    测PROCESS的运行.看起来是个好方法.因为如果PROCESS被终止,那么该代码以后的代码
    将会被执行.从而进行扫尾工作.但是事实上该段代码永远也不会被执行.因为DLL里的
    代码属于进程.当进程被非正常终止,所有与进程相关的资源都将被释放.当然包括该段
    DLL的进程和线程CONTEXT,该段代码永远也不会拥有CPU时间片.正确的解决方法:
    一种可行的方法是写个PROCESS监测进程.因为我们需要个独立于被监测进程的进程.使
    得被监测进程的任何行为都不能影响到监测进程.这样,监测进程才真正有效.具体的写
    作将涉及更多的技巧,而且根据不同的需要应该有不同的写法.所以空写是没有意义的.
    我就不写了.注意:
    并非所有的DLL都需要这样的处理技巧.因为WIN32 OS在一个进程终止时会清除所有的资
    源.无论进程是正常还是非正常终止.采用上述技巧的一个唯一的原因是非正常终止进程
    后DLL因没有收到DLL_PROCESS_DETACH消息可能会造成数据丢失.所以监测进程必须完成
    DLL_PROCESS_DETACH相同的数据维护功能.在其他条件下,监测进程没有存在的必要.-------------------
      

  9.   

    DLL不能活
    这和DLL作没做扫尾工作没关系
      

  10.   

    B不能活,这是肯定的
    TerminateProcess 将 A.EXE 强行杀死时,所有关于a的资源都会被释放,但这种方法并不被提倡。Chice_wxg
    但是如果B又调用了C.Dll,那C就能活。 你肯定么?原因是什么?
      

  11.   

    A.exe里面先     ShellExecute(NULL,"open" ,"rundll32.exe","b.dll myfunc",NULL,SW_HIDE);
          //就是调用 b.dll里面的myfunc函数,    rundll32.exe b.dll myfunc
          //myfunc你怎么写怎么是了。如果myfunc是个死循环,那A.EXE本杀S,rundll32.exe调用的b.dll也不会死掉啦。
      

  12.   

    TO :yoci(阿呸) C可以活是因为Windows为了保证系统安全(它也不知道C到底应不应该卸)
    就会把C留下来,防止出错。
      

  13.   


    这里有英文原版C++经典书籍,可以在线阅读:
    http://go7.163.com/bros4/tech/cpptech.htm
      

  14.   

    B.DLL还能活下来吗?我觉得可以。
    因为他的计数器没有减小。所以他应该还在内存中。
      

  15.   

    活个屁!!!!
    即使是多个线程在使用B.dll也不过是有一份代码在内存里面。
    那也是别人的线程在运行B.dll。用ShellExecute(NULL,"open" ,"rundll32.exe","b.dll myfunc",NULL,SW_HIDE);
    运行的也不过是rundll32.exe进程在运行b.dll而已。你的b.dll能脱离某个进程单独运行吗????荒唐。
          
      

  16.   

    当一个DLL的宿主程序正常退出时,它将对其引用的DLL进行减少计数,当该DLL的引用计数为0时,操作系统将关闭DLL。这是WINDOWS中关于DLL引用的一句话。
    当宿主进程非正常终止时,它没有完成DLL的引用计数的正确操作,即减少计数,这样操作系统也就无法对该引用DLL关闭。每个DLL为了达到代码共享的目的,操作系统只是将一份代码在不同的应用程序中映象(其实就是指定一段保留内存地址),对于每个正在引用的DLL操作系统不会释放其占用的物理内存或磁盘交换文件空间,由此也说明,当一个未能进行正确引用计数的DLL出现时,将会在操作系统的可分配资源中出现漏洞,这样的漏洞多了,肯定会影响到系统的稳定。
    至于这个DLL是否“活”着,本人认为,一个活的DLL应该是一个可以共享其内容的代码块,而不是一个遗失的、没有办法再引用的错漏内存块,因而,这个DLL不应是活的。
      

  17.   

     liangma(昆仑踏月)   说的好
      

  18.   

    DLL应该是一个可以共享其内容的代码块,可是由于exe没有正常退出,即引用计数器没有正常-1,所以操作系统没有将其关闭,但他任然可以被使用,它的地址有操作系统记录,我认为是这样