Why can't I delete a file because it is in use on Windows?

A file refuses to delete because another program holds it open. Confirm the lock, find the owner, close it, then remove the file for good.

WindowsProcessesFilescmdmemorytroubleshootingpowershellMedium risk
Confirm the file is really locked with an exclusive-open test, then close the process that holds it and delete the file.

What this covers

Windows blocks deletion while any process holds a handle to the file — a half-open Excel workbook, a paused OneDrive sync, a media player, or an antivirus scan. This guide walks from confirming the lock to removing the file, and covers the two cases that masquerade as a lock: a network share opened on another PC, and NTFS permissions.

Symptom

?Explorer shows 'The action can't be completed because the file is open in another program', or delete, rename and move all fail with 'used by another process'. The file may be a document, a log, a video, or a folder containing one.

Confirm the file is really locked

Attempt to open the file with an exclusive handle that allows no sharing. If the open succeeds, nothing has it locked — your failure is permissions or path related, so skip the process hunting and check the ACL instead. If it throws a sharing-violation error, another process holds the handle, and you can continue.

Test whether another program is holding a file open by attempting an exclusive .NET File.Open inside try/catch.

Command
$ try {
  $fs = [System.IO.File]::Open('C:\Temp\report.xlsx', 'Open', 'ReadWrite', 'None')
  $fs.Close(); 'File is NOT locked'
} catch { 'File IS locked: ' + $_.Exception.Message }

Spot the app that probably holds the file

List running processes with their memory footprint and look for the usual suspects: Office apps, PDF readers, media players, sync clients (OneDrive, Dropbox), backup tools and Explorer itself. Note the name and PID of the one that plausibly opened the file — you need that identifier for the next step. Memory size is a hint, not proof: a 30 MB Word process can hold a 2 GB document just fine.

Rank running processes by working-set memory and CPU time in one PowerShell pipeline.

Command
$ Get-Process | Sort-Object WS -Descending | Select-Object -First 15 Name, Id, @{n='Mem(MB)';e={[math]::Round($_.WS/1MB,1)}}, @{n='CPU(s)';e={[math]::Round($_.CPU,1)}} | Format-Table -AutoSize

Rule out another computer holding it over a share

If the file lives in a shared folder, the handle can belong to someone else on the network: they opened it and left it open. This lists every file currently opened on your shares and lets you cut the offending session by its ID. It only returns rows when file sharing and the objects list are enabled, so an empty result on a home PC is normal and not a dead end.

List every file that other computers on the network have opened on your shared folders with openfiles /query, and cut a session with /disconnect.

Command
$ openfiles /query /fo table
# disconnect a specific open file by ID:
openfiles /disconnect /id 1234

Rule out a permissions problem in disguise

An Access Denied error on delete often reads to users like 'in use'. Dump the file's ACL to see who owns it and what your account is allowed to do. If your account only has Read, or the file is owned by SYSTEM from an installer, no amount of closing processes will help — you need to take ownership or grant write and delete rights first.

Dump the ACL of any file or folder with icacls, then grant, deny or reset permissions with inheritance control.

Command
$ icacls "D:\Data"

Close the process that holds the file

End the offending process by image name or by the PID you identified. Use the non-forced form first so the app can prompt to save; add the forced switch only when it refuses to quit, since that discards unsaved work. Close the whole application rather than an individual window — a background window in the same process still holds the handle.

End an unresponsive application from Command Prompt using taskkill by image name or PID.

Command
$ taskkill /IM notepad.exe /F  ::  or by process id:  taskkill /PID 12345 /F

Delete the file to the Recycle Bin

Remove the file with a recycle-bin delete, so a mistake stays recoverable. This works for a single file or a whole directory. If deletion still fails here, a handle was re-taken between the two steps — re-run the exclusive-open test and repeat the process hunt rather than reaching for a permanent delete.

Use Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile/DeleteDirectory with SendToRecycleBin for recoverable deletes in scripts.

Command
$ Add-Type -AssemblyName Microsoft.VisualBasic
[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile('C:\Temp\old.txt', 'OnlyErrorDialogs', 'SendToRecycleBin')

Verify the file is gone

Check whether the path still exists. A false result confirms the file was really removed and no process recreated it. If it is still true, something is recreating or re-locking the file — a running sync client that restores it, or an app that reopens the path on a timer — and that process, not the file, is the real problem.

The PowerShell true/false existence test every script should start with — supports files, folders, registry keys, and wildcards.

Command
$ Test-Path 'C:\Program Files\Git\bin\git.exe'
!Force-closing a process discards unsaved work — save anything you can from the offending app first. Never force-kill core system processes (lsass, csrss, wininit, services); on a shared machine, disconnecting an open file session kicks the other user out mid-write.

How to confirm it worked

The file no longer appears in Explorer, and a path existence test returns false for its location.

Sources

  • FileStream Class
    Microsoft Learn · vendor-doc · 2026-09-17
    Evidence: FileStream with FileShare.None throws IOException when the file is already open elsewhere, the mechanism behind the lock test.
  • File.Open(String, FileMode, FileAccess, FileShare) Method
    Microsoft Learn · vendor-doc · 2026-09-17
    Evidence: File.Open with FileShare.None throws IOException when another process holds the file open, which is the basis of the lock test.
  • Get-Process - SS64
    SS64 · technical · 2026-09-17
    Evidence: Shows sorting processes by working set and other memory-oriented examples.
  • Get-Process
    Microsoft Learn · vendor-doc · 2026-09-17
    Evidence: Documents Get-Process objects and their WS and CPU properties.
  • Openfiles - List or Disconnect Open Files - SS64
    SS64 · community · 2026-09-17
    Evidence: Documents /query listing remotely opened files and /disconnect closing them by ID or name.
  • openfiles command | Microsoft Learn
    Microsoft · vendor-doc · 2026-09-17
    Evidence: openfiles /query lists files opened from the local system by remote users; openfiles /disconnect /id <id> disconnects a specific open file.
  • ICACLS - Windows CMD
    SS64 · technical · 2026-09-17
    Evidence: SS64 details icacls syntax for /grant, /deny, /remove and the inheritance rights letters (OI, CI, IO, NP) used in ACE entries.
  • icacls | Microsoft Learn
    Microsoft · vendor-doc · 2026-09-17
    Evidence: Microsoft documents icacls for displaying and modifying discretionary access control lists (DACLs), including /grant with inheritance flags like (OI)(CI).

Last verified: 2026-09-22

Related guides