Unable to access file that is in use - c#

I have written an Add-in for Windows Home Server Console that is supposed to copy and replace some files among other things.
The problem is that one file is already used by HomeServerConsole.exe and therefore I cannot replace it with another. I get "Cannot access file because it's being used by another process".
I'm not sure how to solve this. My first idea was to programmatically close HomeServerConsole.exe and lauch another simple program to do the replacing. How do I do that though?
Another idea was to somehow get HomeServerConsole.exe to unlock the file for me to do my thing and then handing it back to HomeServerConsole. But how?
I've also begun looking at Win32Api to solve the problem but haven't yet found a solution.
How would you go about solving it?

These methods require a reboot:
How to replace in-use files at Windows restart

Related

File.ReadAllBytes keeps file handle open

I have this piece of code, which loads a file into RAM, then loads it as an assembly into an AppDomain (d):
var a = d.Load(File.ReadAllBytes(tmp));
The problem is that when I later try to delete the file located at tmp (right now just using File Explorer), I get an error saying that the file is still open in my program. I even tried using the using keyword with File.Open, and that didn't seem to work either. Can someone please explain why this might be happening, and how to fix it?
ReadAllBytes is supposed to close the file as part of its function. It sounds like something is preventing it from closing, and therefore you cannot delete. Maybe there's an exception happening that needs to be caught.
Here is a similar question with a solution which may be helpful:
Unable to delete some files via System.IO.File in C# console app

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.

How to make a running excutable delete its own file

For example,
I have an excutable TrashClean.exe running. I want it to delete all files I don't want and also delete itself (TrashClean.exe on hard drive) at last step.
I am wondering if it's possible in C#?
Please see How To Make Your Application Delete Itself Immediately:
I'm sure you've all said to yourself
or someone at the office at one point
or another, "<snort> You idiot. Don't
you know a Windows application can't
delete itself? I bet you don't even
know how to type high ASCII characters
using the ALT key and the number pad,
gahhhh.."
Sure, there are ways to have a file
delete itself on the next reboot...
And you can even resort to an external
program or batch file to do the work.
But I just came up with a nifty way of
doing it without leaving a visible
trace that the application ever
existed!

C# Cannot write to Application.ExecutablePath, some boxes i can some i cannot? uninstall from this

So I have been writing to
Environment.SpecialFolder.ApplicationData
this data file, that upon uninstall needs to be deleted. I am using Innos Setup to build my installer. It works great for me. So my data file hangs out in the above path and I do that cause when I used to try to write it to
Application.ExecutablePath
certain boxes I tested it on would throw a nasty error at me trying to write data there. I do research and somehow its not always writable and its how i came up with the Environment.SpecialFolder.ApplicationData
That is why my data file now resides in the SpecialFolder.ApplicationData. Trouble is if the user uninstalls and reinstalls I need that file gone. It might be a short coming of my knowledge of Innos but I cannot figure out how to know where that file will be to tell innos that.
So then I thought I had a clever solution: Innos can run a file when its done uninstalling, so I had my program create this file "uninstallData.bat" that says:
del "the file in my special folder application data path"
and I wrote it out to drumroll
Application.ExecutablePath
(yes it was a while in development and I had forgot it was't doable.)
So of course I am back to square one, I need to write a file to a path Innos knows about {app} and I need it to be able to delete my data file in the SpecialFolder... i don't care how I do it i just need that file gone.
Are there other Environment. or Application. approches I have missed? Maybe somewhere that is viewable by an uninstaller AND can be written to?
As an aside, I am not sure why my box I develop on can write to the application folder no issue, but it cannot on other boxes... weird.
Any input would be great sorta lost as to how to crack this nut.
The environment location is in the user profile. If there are multiple users on the machine, and they all run the application then a copy of the file will be in each profile.
The path also depends on the OS.
Regardless, the current user's app data location is pointed to by %APPDATA% and %LOCALAPPDATA%. These Windows environment variables should be available within Innos.
Appliccation.ExecutablePath is not writable per standard defintions - the program files folder should never be manipulated by running applications. Ther area number of special folders for that. Nice that you finally found.... what is properly documented by Microsoft for a LONG time now (minimum 10 years).
I suggest you get a proper installer - WIX comes to my mind. Your problem is totally unrelated to C# - it seems to be totally a "crappy installer" issue. Or provide a PROGRAM (not bat file) to run at uninstall. What exatly is your problem there?

How can I tell what files are currently open by a process (i.e. my app)?

I am using a Lucene.Net index and want to give the user an option to move the index, but am having trouble closing it down so the directory/contents can be moved (I keep getting access denied exceptions). I need to be able to have some more information so I can debug this problem, such as being able to tell what files are currently open, and as much information about each use as possible.
Alternatively, is there any way to simply force close a bunch of files so they can be moved? This would make things a lot easier to solve.
You can use Process Explorer to find out which process has opened a file.

Categories

Resources