14

When I try to delete a file occurs the following exception:

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

My code looks like:

string[] files = Directory.GetFiles(@"C:\SEDocumentConverter\SOURCE");
foreach (string file in files)
{               
   File.Delete(file);
}

How can I solve this problem?

4
  • 2
    Find out which other process is accessing the file, and stop it doing so. Commented Mar 8, 2011 at 12:48
  • Do you have one of the files open in an editor? Were you working with one of the files earlier in your program and perhaps leave a stream open? Commented Mar 8, 2011 at 12:50
  • Is the error as you have typed - i.e. an empty filename is returned or have you just removed the name for the question? Commented Mar 8, 2011 at 12:50
  • you can follow this solution stackoverflow.com/questions/13262548/… Commented Feb 25, 2016 at 11:03

7 Answers 7

10

There is no way to delete a file that's currently being used by another process. You have to close whatever program has that file open first, before you can delete it.

If you don't already know which program that is, you can figure it out using Handle or Process Explorer.

Sign up to request clarification or add additional context in comments.

1 Comment

With Process Explorer you can also remove the handle without closing the program (if you are sure that the program can happily live without the handle).
4

You can P/Invoke the Windows MoveFileEx function, and use the MOVEFILE_DELAY_UNTIL_REBOOT flag, with a NULL destination name. This will delete the file when you reboot.

1 Comment

Note that, as the documentation indicates, this flag can only be used if the process is running in the context of a user who is an Administrator. And this is probably overkill for standard document files. You shouldn't be moving paging files from a .NET application in the first place.
0

If the file is being used you're out of luck in trying to delete it. I can't tell you based on your code what process might be using the file(s), but try looking here or here or here, or at any of the other questions that show up as related to this one for guidance regarding this issue, and by all means follow the guidance from @Cody Gray about using Process Explorer.

2 Comments

Wow, that's incredible. There are at least 3 other questions with titles exactly matching the original title of this question.
Yeah, who knew? And as a note to @Suresh - you should see a list of questions that Stack Overflow thinks are like the one you're asking when you type in the subject line for your question. If you check those out first, you might find your answer and save yourself the trouble of posting.
0

slightly off topic: But it seems from your code that you are trying to delete all files of your folder. Well instead of deleting them one by one we have another method Directory.Delete(path, True) which will delete the directory as contained in the string named path. Then you may recreate the directory if you want. But your problem may persist here too.

Comments

0

Another way is to find all open handles to the file and close them forcibly.

Works nice for you, bad for any apps which were using the file.

Could try that in UI with SysInternals ProcessExplorer.

Comments

0

Here is automated script with handle (if you have already handle installed) , it does the job:

$delteFolderPath="C:\Sources"
$handleExePath="C:\ProgramData\chocolatey\lib\sysinternals\tools\handle64.exe"
echo $delteFolderPath
if ((Test-Path -Path "$delteFolderPath" ) -and (Test-Path -Path "$handleExePath")) {
    Write-Host "Both paths exist. Continuing the script..."
    
} else {
    Write-Host "One or both paths do not exist. Breaking the script."
    exit
}
$process = & "$handleExePath" -nobanner -v "$delteFolderPath"
echo $process

$csvData = $process

$csvObject = $csvData | ConvertFrom-Csv


$jsonData = $csvObject | ConvertTo-Json -Depth 3


echo $jsonData

$parsed_json = $jsonData | ConvertFrom-Json
$pids = $parsed_json | Select-Object -ExpandProperty PID
echo $pids


$results = @()

# Execute command for each PID
foreach ($processId in $pids) {
    Write-Host "Processing PID: $processId"
    
    try {
       
        $output = Stop-Process -Id $processId -Force -ErrorAction Stop
        
        
        $parsedOutput = $output | ConvertFrom-Json
        
       
        $results += @{
            PID = $processId
            Result = $parsedOutput
        }
    }
    catch {
        
        Write-Warning "Failed to process PID: $processId. Error: $_"
    }
}


$jsonResults = $results | ConvertTo-Json -Depth 5


Write-Host "Combined Output:"
$jsonResults

Remove-Item -Path "$delteFolderPath" -Recurse -Force

Comments

-2

Just rename this file. This will do the thing for whoever tries to write to that location.

Notes:

1) Of course the file is not deleted physically yet. Nice to do the MoveFileEx trick mentioned here around to complete the job.

2) If you want to delete a locked file to write smth new in its place (e.g. during build), just rename the file to a GUID name. If you need the folder to be clean, either use an ignored extension / hidden attribute, or rename the file to a path under %TEMP% (if on the same drive).

3) Not all locked files can be renamed, but it works for me for like 90% practical applications. You can move a file without affecting an open read/write/execute handle, it will continue working with the moved file just good (if moved within the same NTFS volume of course).

4) That's what Windows Installer would basically do before it asks you to please reboot somewhen soon: move the file away from your eyes, schedule to be removed upon reboot. Usually the newly-installed app can be used right away.

Practical Use:

My favorite is with MSBuild. Overriding the <Copy/> task with this stuff makes all the build go linux-way. You don't care if a prev version is still running somewhere, can still build&run. The old app keeps using the old version of the files. The new app loads the newly-written version.

Might be moving to %TEMP% if on the same drive (not my case though). I'd just rename them to an extension which is ignored with the current source control client.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.