Can't delete exe file even when no users are using it - c#

I have a very simple C# application. I copy the exe file other to a shared directory where my team (only 4 of us) can use the app.
A recent problem is this, we need to update the app. So I create a new app. I then delete the exe file from the shared directory and the exe file is no longer there however if I refresh the directory it comes back. No of the other users have it open? This stops me copying over the new version.
Why is this happening? How can I check if anyone does have the app open? As you can probably tell from my post I'm not overly technical. Any help would be great.

Use Unlocker to see what locks your file and kill it.

To resolve this issue, find the process that has the open handle, and then close that process.
You can use Process Explorer or the handle command to determine which process is using the file.

Related

Why `FileShare.Read` doesn't work in combination with `FileOptions.DeleteOnClose`? [duplicate]

Language used: C#
Theory:
I want to create a file with the flag FileOptions.DeleteOnClose in a temporary folder.
The file is successfully created and I write dato onto it, the next step is to launch the application associated with the file Process.Start(...) and allow the user to inspect the document, finally I close my handle and as soon as other process close the handle to the temporary file, the file is deleted by operating system.
My problem is that other processes cannot open the file, even for reading, despite if I add FileShare.ReadWrite | FileShare.Delete to the sharing mode.
Any suggestions?
The other processes need to specify FileShare.Delete when they open the DeleteOnClose file
From the MSDN CreateFile docs:
"FILE_FLAG_DELETE_ON_CLOSE... Subsequent open requests for the file fail, unless the FILE_SHARE_DELETE share mode is specified."
Check this:
You need to make sure that all processes are opening the file with FileShare.ReadWrite and FileShare.Delete.
Even if the creator opens with share-readwrite, if a second program tries to open with share-read, the second program is basically saying no-one else can write. But the first program already has that power so the second open fails.
Switch to Linux scnr
Ok, seriously now: That is a flaw in the Windows operating system which can't really be worked around. Each program opening the file must agree on other programs having the file open in the same time. That was a problem I got many years back when I still used Windows as well. It doesn't suffice to open a file and say: Let anyone else open this as well. The others must also say open this file even if it's open already.
On Linux on the contrary, the operating system doesn't allow any file locking in the way Windows does at all. Here, if any file is used by more than one program simultaneously, the programs itself must make sure, that concurrent accesses get locked out. Additionally, on Linux, we can just create the file, make sure the other process has been started and opened the file and then just delete the file (while it is open). The filename is then removed from the file system immediatelly, but the file is still maintained by the file system driver until the last link (including open file handles) got removed.
Back to your problem: As all of this doen't work on Windows, you could do two other approaches:
Register the file to be deleted on next boot (in the Win3x days, there was a section in the win.ini for that. Newer Windows version still support that, I just can't recall any longer, how it's done now).
Start the other process, wait for it to open the file, close the file and then try each minute to delete the file until deletion succeeds ...
Regards, Bodo

Close the app.config file after reading

My "app" is being hijacked by a monitoring service. After it dies, for some reason the app.config file is considered still in use, so I can't make changes.
The only thing I can do is rename the existing file, and save a new file with the old name.
This is not an interactive app, so I want to simply want to use notepad to make changes in the file between runs.
Here is what I would try:
Use Unlocker to figure out what service or process holds a handle to your file and "unlock" it
Try ProcessExplorer. In menu go to Find > Find handle or DLL, search for your .config file and figure out what process is "taking a lock" on the file
Once you figure out what's causing this, check if you can somehow add an exception for your file, so that it's not trying to open this config file - very unlikely but an AV process may do that. Other solutions is to kill a misbehaving 3rd party app and start it once you finished editing config file.
Double check that your app was actually killed and no longer runs. Use process explorer or default task manager (or any other similar tool on non-Windows OS).

How can I delete a file that is in use by another process?

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?
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.
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.
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.
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.
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.
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.

Need to find a way to programmatically delete undeleteable empty folders

I've got a large folder on an offsite backup machine that gets populated with files by rsync (through deltacopy) every night (running windows xp) from the main work site. I've discovered some annoying folders that cannot be opened, or deleted, or even checked for file sizes. I get the such and such a folder is not accessible, access is denied message when I try to click on it in windows explorer. According to the windows explorer tooltip they are also "empty" and the properties of these folders say 0 bytes and 0 files.
I currently have a C# program that goes through every folder and file and tries to copy the whole backup directory to a dated backup-backup directory, which is how i discovered this problem in the first place. The regular System.IO library seems helpless against these blasted folders. Exceptions are thrown when I even try to access the folder path.
Does anyone have any clue how I could, say, on an access denied exception in my existing copy code, force the delete of these folders so rysnc can recreate the directory again and get the whole thing synced again?
First thing I think of when I see this is time to do a checkdisk. From the sounds of it, it feels more like a file system problem than something solvable the way you want to go about it.
Yes, try the awesome "Process Explorer" from Microsoft (formerly SysInternals).
Although it's for the processes in the windows filesystem, you could search for your folder in the explorer window & it will tell you who is locking it.
Once you release the process, your program would be able to delete the folder.
If that doesn't work, see if you can specify additional parameters to bruteforce the delete in your program.
It sounds like the filenames are either bad or contain characters that are invalid in Win32. Did you try to delete the directories with rd /r? Did you do a dir /x on them and try to delete the files/directories using their short names?
I would say that you first have to figure out why you can't delete the folders. Once you figure that out, you can write a program to fix it.
OK, so now that you know it's a permissions problem, the first step is to take ownership of the files (so you can set the permissions), then change the permissions so that you can delete the files.
Here's code to take ownership of a file:
WindowsIdentity currentUser = System.Security.Principal.WindowsIdentity.GetCurrent();
FileSecurity acl = File.GetAccessControl(filename);
acl.SetOwner(currentUser.User);
File.SetAccessControl(filename, security);
The trouble was that SYSTEM owned these files. I set deltacopy to run as administrator so that administrator would own the files deltacopy makes.
I guess windows is doing its job. The permissions are airtight. But if this happens again someday where I'd have to grab ownership from some other user to the current user (who has administrator permissions) how would I do that in code?
A question for another day I suppose. Thanks again everyone.

Delete on close files

Language used: C#
Theory:
I want to create a file with the flag FileOptions.DeleteOnClose in a temporary folder.
The file is successfully created and I write dato onto it, the next step is to launch the application associated with the file Process.Start(...) and allow the user to inspect the document, finally I close my handle and as soon as other process close the handle to the temporary file, the file is deleted by operating system.
My problem is that other processes cannot open the file, even for reading, despite if I add FileShare.ReadWrite | FileShare.Delete to the sharing mode.
Any suggestions?
The other processes need to specify FileShare.Delete when they open the DeleteOnClose file
From the MSDN CreateFile docs:
"FILE_FLAG_DELETE_ON_CLOSE... Subsequent open requests for the file fail, unless the FILE_SHARE_DELETE share mode is specified."
Check this:
You need to make sure that all processes are opening the file with FileShare.ReadWrite and FileShare.Delete.
Even if the creator opens with share-readwrite, if a second program tries to open with share-read, the second program is basically saying no-one else can write. But the first program already has that power so the second open fails.
Switch to Linux scnr
Ok, seriously now: That is a flaw in the Windows operating system which can't really be worked around. Each program opening the file must agree on other programs having the file open in the same time. That was a problem I got many years back when I still used Windows as well. It doesn't suffice to open a file and say: Let anyone else open this as well. The others must also say open this file even if it's open already.
On Linux on the contrary, the operating system doesn't allow any file locking in the way Windows does at all. Here, if any file is used by more than one program simultaneously, the programs itself must make sure, that concurrent accesses get locked out. Additionally, on Linux, we can just create the file, make sure the other process has been started and opened the file and then just delete the file (while it is open). The filename is then removed from the file system immediatelly, but the file is still maintained by the file system driver until the last link (including open file handles) got removed.
Back to your problem: As all of this doen't work on Windows, you could do two other approaches:
Register the file to be deleted on next boot (in the Win3x days, there was a section in the win.ini for that. Newer Windows version still support that, I just can't recall any longer, how it's done now).
Start the other process, wait for it to open the file, close the file and then try each minute to delete the file until deletion succeeds ...
Regards, Bodo

Categories

Resources