批量解除文件占用的脚本

wen 实用脚本 1

本文目录导读:

批量解除文件占用的脚本

  1. 方案一:Windows PowerShell 脚本(推荐)
  2. 方案二:Windows 批处理脚本
  3. 方案三:Python 脚本(跨平台)
  4. 使用方法:
  5. 注意事项:

Windows PowerShell 脚本(推荐)

# Unlock-Files.ps1
# 批量解除文件占用脚本
# 方法1:使用 handle.exe (Sysinternals)
function Unlock-FilesWithHandle {
    param(
        [string]$Path = "C:\",
        [string]$HandleTool = "C:\Tools\handle64.exe"
    )
    if (-not (Test-Path $HandleTool)) {
        Write-Host "handle.exe 未找到,请从 https://docs.microsoft.com/sysinternals/downloads/handle 下载" -ForegroundColor Red
        return
    }
    $files = Get-ChildItem -Path $Path -Recurse -ErrorAction SilentlyContinue | Where-Object { -not $_.PSIsContainer }
    foreach ($file in $files) {
        $filePath = $file.FullName
        $output = & $HandleTool $filePath 2>&1
        if ($output -match "pid:") {
            Write-Host "发现占用: $filePath" -ForegroundColor Yellow
            $matches = [regex]::Matches($output, "pid: (\d+)")
            foreach ($match in $matches) {
                $pid = $match.Groups[1].Value
                Write-Host "  尝试终止进程: PID $pid" -ForegroundColor Cyan
                Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue
            }
        }
    }
}
# 方法2:使用 openfiles (Windows 内置命令)
function Unlock-FilesWithOpenFiles {
    param(
        [string]$Path = "C:\"
    )
    # 需要管理员权限
    if (!(Test-Path "$env:WINDIR\System32\openfiles.exe")) {
        Write-Host "openfiles 命令不可用,请以管理员身份运行" -ForegroundColor Red
        return
    }
    # 启用全局文件连接
    openfiles /global on | Out-Null
    Write-Host "正在刷新文件连接..." -ForegroundColor Green
    openfiles /query /fo CSV | ConvertFrom-Csv | ForEach-Object {
        $filePath = $_.'打开的文件'
        if ($filePath -like "*$Path*") {
            Write-Host "找到占用: $filePath" -ForegroundColor Yellow
            $session = $_.'会话'
            if ($session -ne "本地") {
                # 终止远程会话
                openfiles /disconnect /id $_.'ID' /y
            }
        }
    }
}
# 方法3:批处理方式终止所有相关进程
function Unlock-FilesByProcess {
    param(
        [string[]]$ProcessNames = @("explorer", "winword", "excel")  # 添加要终止的进程名
    )
    foreach ($processName in $ProcessNames) {
        Write-Host "正在终止进程: $processName" -ForegroundColor Yellow
        Get-Process -Name $processName -ErrorAction SilentlyContinue | Stop-Process -Force
        Write-Host "  $processName 已终止" -ForegroundColor Green
    }
    # 重启 Explorer(可选)
    Start-Sleep -Seconds 2
    Start-Process explorer.exe
}
# 主菜单
Write-Host @"
========================================
     文件占用批量解除工具
========================================
1. 使用 handle.exe 查找并解除
2. 使用 openfiles 命令解除
3. 终止指定进程
4. 使用所有方法(推荐)
5. 退出
"@
$choice = Read-Host "请选择操作 (1-5)"
switch ($choice) {
    "1" { 
        $path = Read-Host "请输入要检查的路径(回车默认C:\)"
        if ($path -eq "") { $path = "C:\" }
        Unlock-FilesWithHandle -Path $path
    }
    "2" {
        $path = Read-Host "请输入要检查的路径(回车默认C:\)"
        if ($path -eq "") { $path = "C:\" }
        Unlock-FilesWithOpenFiles -Path $path
    }
    "3" {
        $processes = Read-Host "请输入要终止的进程名(用逗号分隔)"
        $processList = $processes -split ","
        Unlock-FilesByProcess -ProcessNames $processList
    }
    "4" {
        Write-Host "正在使用所有方法解除文件占用..." -ForegroundColor Green
        $path = Read-Host "请输入要检查的路径(回车默认C:\)"
        if ($path -eq "") { $path = "C:\" }
        # 方法1
        Unlock-FilesWithHandle -Path $path
        # 方法2
        Unlock-FilesWithOpenFiles -Path $path
        # 方法3 - 常见占用的进程
        Unlock-FilesByProcess -ProcessNames @("explorer", "SearchIndexer", "WindowsSearch")
    }
    "5" { exit }
    default { Write-Host "无效选择" -ForegroundColor Red }
}

Windows 批处理脚本

@echo off
chcp 65001 >nul批量解除文件占用工具
color 0a
:menu
cls
echo ========================================
echo      文件占用批量解除工具
echo ========================================
echo.
echo 1. 终止 explorer.exe(解除大部分文件锁定)
echo 2. 使用 OpenFiles 命令解除临时文件锁定
echo 3. 强制终止所有占用指定文件的进程
echo 4. 清理文件缓存
echo 5. 退出
echo.
set /p choice=请选择操作:
if "%choice%"=="1" goto kill_explorer
if "%choice%"=="2" goto openfiles_method
if "%choice%"=="3" goto force_unlock
if "%choice%"=="4" goto clear_cache
if "%choice%"=="5" exit
goto menu
:kill_explorer
echo.
echo 正在终止 explorer.exe...
taskkill /f /im explorer.exe 2>nul
echo.
echo 终止完成,正在重启资源管理器...
start explorer.exe
echo.
pause
goto menu
:openfiles_method
echo.
echo 需要管理员权限运行...
echo 正在启用全局文件追踪...
openfiles /global on
echo.
echo 正在查询打开的文件...
openfiles /query /fo table > "%TEMP%\openfiles.txt"
type "%TEMP%\openfiles.txt"
echo.
set /p endorn=是否终止以上所有会话连接?(Y/N):
if /i "%endorn%"=="Y" (
    for /f "skip=1 tokens=1" %%i in ('openfiles /query /fo csv^|findstr /v "本地"') do (
        evmonitor /disconnect /id %%i /y
    )
)
pause
goto menu
:force_unlock
echo.
set /p file_path=请输入文件或文件夹路径:
if not exist "%file_path%" (
    echo 路径不存在!
    pause
    goto menu
)
echo.
echo 正在查找占用进程...
handle.exe -a "%file_path%" 2>nul
if errorlevel 1 (
    echo 未找到占用进程,或需要安装 handle.exe
    echo 请从 https://docs.microsoft.com/sysinternals/downloads/handle 下载
    pause
    goto menu
)
echo.
pause
goto menu
:clear_cache
echo.
echo 正在清理系统缓存...
ipconfig /flushdns >nul
del /q /f "%TEMP%\*" 2>nul
del /q /f "%TEMP%\Prefetch\*" 2>nul
echo 缓存清理完成!
pause
goto menu

Python 脚本(跨平台)

# unlock_files.py
import os
import sys
import subprocess
import psutil
import platform
import time
def find_locked_files_windows(path):
    """Windows 下查找被锁定的文件"""
    locked_files = []
    # 使用 handle.exe 或 try/except
    for root, dirs, files in os.walk(path):
        for file_name in files:
            file_path = os.path.join(root, file_name)
            try:
                # 尝试打开文件
                with open(file_path, 'a+'):
                    pass
            except PermissionError:
                locked_files.append(file_path)
                print(f"发现锁定文件: {file_path}")
    return locked_files
def kill_process_using_file(file_path):
    """终止使用该文件的进程"""
    if platform.system() == 'Windows':
        # 使用 Windows API
        for proc in psutil.process_iter(['pid', 'name']):
            try:
                # 检查进程是否有该文件句柄
                if hasattr(proc, 'open_files'):
                    for item in proc.open_files():
                        if item.path == file_path:
                            print(f"终止进程 {proc.name()} (PID: {proc.pid})")
                            proc.terminate()
                            time.sleep(1)
                            if proc.is_running():
                                proc.kill()
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                continue
    else:
        # Unix/Linux 使用 lsof
        try:
            result = subprocess.run(
                ['lsof', file_path],
                capture_output=True,
                text=True
            )
            if result.returncode == 0:
                lines = result.stdout.split('\n')[1:]  # 跳过标题行
                for line in lines:
                    if line.strip():
                        parts = line.split()
                        if len(parts) > 1:
                            pid = parts[1]
                            process_name = parts[0]
                            print(f"终止进程: {process_name} (PID: {pid})")
                            os.kill(int(pid), 9)
        except FileNotFoundError:
            print("需要安装 lsof")
def delete_after_unlock(path):
    """解锁后删除文件"""
    try:
        os.remove(path)
        print(f"已删除文件: {path}")
    except Exception as e:
        print(f"删除文件失败: {e}")
def batch_unlock(path):
    """批量解锁指定目录下的所有被锁文件"""
    print(f"正在扫描目录: {path}")
    if not os.path.exists(path):
        print("路径不存在!")
        return
    locked_files = find_locked_files_windows(path)
    if not locked_files:
        print("未发现被锁定的文件")
        return
    print(f"\n发现 {len(locked_files)} 个被锁定文件")
    print("=" * 50)
    # 显示所有锁定文件
    for i, file_path in enumerate(locked_files, 1):
        print(f"{i}. {file_path}")
    print("\n开始解除文件占用...")
    for file_path in locked_files:
        kill_process_using_file(file_path)
    print("\n解锁完成!")
    # 询问是否删除
    delete_choice = input("\n是否删除这些文件?(Y/N): ").upper()
    if delete_choice == 'Y':
        for file_path in locked_files:
            delete_after_unlock(file_path)
        else:
            print("文件保留,未删除")
if __name__ == "__main__":
    if len(sys.argv) > 1:
        path = sys.argv[1]
    else:
        path = input("请输入要解锁的目录或文件路径: ")
    batch_unlock(path)

使用方法:

PowerShell 脚本:

# 保存为 Unlock-Files.ps1,然后运行
powershell -ExecutionPolicy Bypass -File .\Unlock-Files.ps1

批处理脚本:

# 保存为 unlock.bat,右键以管理员身份运行
unlock.bat

Python 脚本:

# 需要安装依赖
pip install psutil
# 运行脚本
python unlock_files.py C:\path\to\your\files

注意事项:

  1. 需要管理员权限:大多数解锁操作需要在管理员权限下运行
  2. handle.exe 下载:如果使用 handle.exe,需要从微软官网下载
  3. 谨慎操作:终止进程可能导致数据丢失,请先保存重要数据
  4. 备份文件:在进行批量操作前建议备份重要文件

选择最适合你需求的脚本,如需要修改或调整,请告诉我!

抱歉,评论功能暂时关闭!