写了一个windows explorer shell extension,使用效果还不错,但是一旦注册使用了这个shell extension,如果想删除的话,把这个shell extension给它unregister了,但此时删除shell extension(DLL文件)时报错,说资源管理器打开了这个文件,也就是说虽然unregister了,但还是没有被释放,如何删除这个文件??当然在重新启动后,或者注销系统后,explorer可以释放这个DLL,是可以删除的。我也知道如果把所有的explorer给它kill了,然后再启动一个,也可以释放这个DLL,但这样的话因为先要关闭所有的explorer,桌面会消失再出现,会闪一下。有没有办法在不关闭explorer的情况下,让其重新加载所有的shell extensions呢?

解决方案 »

  1.   

    不kill explorer是没有办法的,常见的正规做法是在卸载程序里设置重启后删除,卸载完成后询问用户是否立即重启。
      

  2.   

    强行关掉explorer.exe和dll的关联.
      

  3.   

    你把它的句柄用ProcessExplorer关掉
      

  4.   

    同意,我以前做也是这样的,需要重启explorer.exe进程。
    再说,你在unregister这个dll的时候应该也是在卸载程序的时候才用到吧,卸载程序的时候关掉explorer.exe再重启这个进程也是合理的呀
      

  5.   

    LZ做的是哪种 extension ? 有些可以释放,有些却不可以。
      

  6.   

    unregister之后,通过远程线程注入explorer进程去调用FreeLibrary来释放dll。
    然后ZwDeleteFile删除dll文件。以上方法被Unlocker这款软件所使用,LZ不妨一试。
      

  7.   

    LZ google 一下unlocker 逆向  即可找到很多相关文章。
      

  8.   


    BOOL DeleteLockedFile(DWORD dwProcessID, HANDLE hFile)
    {
        TCHAR szTargetName[MAX_PATH] = { 0 };
        HANDLE hTargeFile = INVALID_HANDLE_VALUE;
        HANDLE hProcess = NULL;
        BOOL bResult = FALSE;
        
        do 
        {
            hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
            if (NULL == hProcess) {
                break;
            }
            
            if (FALSE == DuplicateHandle(hProcess, hFile, 
                GetCurrentProcess(), &hTargeFile, 
                0, FALSE, DUPLICATE_SAME_ACCESS)) 
            {
                break;
            }
            
            if (INVALID_HANDLE_VALUE==hTargeFile || NULL==hTargeFile) {
                break;
            }        if (FALSE == GetFilePathFromHandle(hTargeFile, 
                szTargetName, _countof(szTargetName))) 
            {
                break;
            }        CloseHandle(hTargeFile);
            hTargeFile = INVALID_HANDLE_VALUE;
            
            if (0 == lstrlen(szTargetName)) {
                break;
            }
            
            if (FALSE == DuplicateHandle(hProcess, hFile, 
                GetCurrentProcess(), &hTargeFile, 
                0, FALSE, 
                DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE))  // 关键标志
            {
                break;
            }        if (INVALID_HANDLE_VALUE==hTargeFile || NULL==hTargeFile) {
                break;
            }
            
            CloseHandle(hTargeFile);
            hTargeFile = INVALID_HANDLE_VALUE;        bResult = DeleteFile(szTargetName);
        } while (FALSE);    if (INVALID_HANDLE_VALUE != hTargeFile && NULL != hTargeFile) {
            CloseHandle(hTargeFile);
        }
        
        if (hProcess) {
            CloseHandle(hProcess);
        }
        return bResult;
    }
    转自http://www.cppblog.com/free2000fly/archive/2009/12/22/89988.html