Fix 'The process cannot access the file because it is being used by another process' on Windows

intermediate๐ŸชŸ Windows2026-04-16| Windows 10/11, Windows Server 2019/2022 โ€” any app that reads/writes files (Node.js, Python, Java, .NET, build tools, deployment scripts)

Error Message

The process cannot access the file because it is being used by another process.
#windows#file-lock#process#handle#sysinternals

The situation

Mid-deploy, mid-build, or just trying to delete a log file โ€” and Windows throws:

The process cannot access the file because it is being used by another process.

Something has an open handle to that file. Windows won't let you touch it until that handle is closed. Track down what's holding the lock, then either close it gracefully or kill it. That's the whole game.

Debug process

Option 1: Resource Monitor (no install needed)

Built into every Windows install. Good enough for most cases.

  • Press Win + R, type resmon, hit Enter.
  • Go to the CPU tab โ†’ expand Associated Handles.
  • Type the filename (or part of it) in the search box.
  • The list shows the PID and process name holding that handle.

Right-click any result to end the process directly from there.

Option 2: Process Explorer (Sysinternals)

Reaches handles that Resource Monitor misses โ€” worth grabbing if you hit this error regularly.

  • Download from learn.microsoft.com/sysinternals/downloads/process-explorer
  • Run as Administrator.
  • Press Ctrl+F to open Find Handle or DLL.
  • Type the filename. Every process holding that file appears in the list.
  • Double-click the entry โ†’ right-click the handle โ†’ Close Handle.

Close Handle releases the lock without killing the whole process. Handy when the locker is a background thread inside a service you'd rather not restart.

Option 3: Handle.exe (CLI, scriptable)

Also from Sysinternals. Runs in PowerShell or CMD, making it ideal for scripts and remote sessions.

# Download: https://learn.microsoft.com/sysinternals/downloads/handle
# Run as Administrator
handle.exe C:\path\to\locked\file.txt

Output looks like:

node.exe        pid: 14832  type: File  C:\path\to\locked\file.txt
java.exe        pid: 9120   type: File  C:\path\to\locked\file.txt

Close a specific handle by hex ID:

handle.exe -c 1A4 -p 14832 -y

The -y flag skips the confirmation prompt. The hex handle ID comes from the first column of the previous output.

Option 4: PowerShell (no third-party tools)

No Sysinternals required โ€” but this only identifies which process owns the file. You can't close individual handles this way.

$lockedFile = "C:\path\to\locked\file.txt"

Get-Process | ForEach-Object {
    $proc = $_
    try {
        $proc.Modules | Where-Object { $_.FileName -eq $lockedFile } | ForEach-Object {
            [PSCustomObject]@{ PID = $proc.Id; Name = $proc.Name; File = $_.FileName }
        }
    } catch { }
} | Format-Table -AutoSize

This catches DLL-level locks. For general file handles on networked shares, openfiles is another option:

# Enable first (requires reboot):
openfiles /local on

# Then query:
openfiles /query /fo table | findstr /i "filename.txt"

Common culprits

  • Antivirus / Windows Defender โ€” scans files the moment they're written. Extremely common during builds and deployments. Add your project folder to exclusions.
  • Windows Search indexer (SearchIndexer.exe) โ€” jumps on new files immediately. Disable indexing on dev and build directories.
  • Node.js / webpack watch mode โ€” holds handles on every file in the watch tree. All of them.
  • Java processes โ€” JVM locks on .jar files and temp files.
  • IIS / w3wp.exe โ€” locks DLLs in the app directory. Stop the app pool before you deploy.
  • Explorer.exe โ€” thumbnail generation can lock image and video files.
  • VS Code โ€” holds handles on workspace files and git objects while a project is open.

Solutions by scenario

Scenario: Build/deploy fails because a .dll or .exe is locked

# Stop IIS app pool first
Import-Module WebAdministration
Stop-WebAppPool -Name "MyAppPool"

# Do your deploy...

# Restart
Start-WebAppPool -Name "MyAppPool"

Or stop the entire IIS service during deploy:

iisreset /stop
# ... deploy ...
iisreset /start

Scenario: Can't delete a file, locker unknown

# 1. Find the PID with handle.exe
handle.exe locked-file.log

# 2. Kill the process (if safe)
Stop-Process -Id 14832 -Force

# 3. Delete the file
Remove-Item locked-file.log

Scenario: Rename/move fails in a script

Sometimes the lock clears in milliseconds โ€” antivirus finishing a scan, for instance. A retry loop handles this cleanly:

$maxRetries = 5
$retryDelay = 1  # seconds
$attempt = 0

while ($attempt -lt $maxRetries) {
    try {
        Move-Item -Path "source.tmp" -Destination "output.txt" -Force -ErrorAction Stop
        Write-Host "Moved successfully"
        break
    } catch {
        $attempt++
        Write-Warning "Attempt $attempt failed: $($_.Exception.Message)"
        Start-Sleep -Seconds $retryDelay
    }
}

if ($attempt -eq $maxRetries) {
    Write-Error "Failed to move file after $maxRetries attempts"
}

Scenario: Antivirus is the locker

Go to Windows Security โ†’ Virus & threat protection โ†’ Manage settings โ†’ Exclusions, then add your build output folder. PowerShell works too:

Add-MpPreference -ExclusionPath "C:\projects\myapp\dist"
Add-MpPreference -ExclusionPath "C:\projects\myapp\node_modules"

Verify the fix

After releasing the lock, confirm nothing is still holding it:

handle.exe C:\path\to\file.txt
# Expected output:
# No matching handles found.

Retry your original operation. If the error comes back immediately, the same process re-acquired the lock. Closing the handle isn't enough โ€” you need to stop the process itself.

What to take away

  • Resource Monitor is already on your machine. Use it first before downloading anything.
  • Keep Handle.exe in C:\tools\ permanently. It pays for itself the first time a deploy breaks at 2am.
  • Windows Defender quietly kills build pipelines on dev machines and CI agents. Add exclusions for build output directories โ€” it's a 30-second fix that saves hours of confusion.
  • Closing a handle via Process Explorer or Handle.exe can crash the owning process. Fine for a one-off unlock; don't automate this in production without understanding what that process was in the middle of doing.
  • If you control the code writing the file: set FileShare explicitly and always close streams in finally blocks or using statements. Most file-lock bugs in custom code trace back to a stream left open after an exception.

Related Error Notes