About assemblies, .NET should open the assembly using something like FileShare.ReadWrite
so, even if it's loaded into the domain, any other process can write or rename the whole file.
AFAIK, .NET doesn't have a managed FileShare
enum value for allowing or disallowing renaming the file share (something like FileShare.Rename
), but Win32 should have thus assembly loading would be creating the file stream with a mask like FileShare.ReadWrite | FileShare.Rename
(FileShare.Delete
includes renaming but also removing the whole file...).
For demonstrating this, I've tried the following code:
FileStream a = File.Open(@"C:\blah.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
a.Dispose();
While the file stream was opened and until it's disposed, I couldn't delete the whole file but I could rename it.
Note that assemblies are loaded into the AppDomain
when they're needed, meaning that maybe you can write, delete or rename an assembly because it's not loaded yet.
Try to delete an assembly already loaded into the AppDomain
: you can't (I've tried myself just now, the test code runs in a console app and I couldn't remove the executable while running it). Now try to rename it: it works.
Summary
It's all about how a file is opened and which file mask configuration was used when the file stream was opened: this is why your file can't be renamed but you can rename an already loaded assembly.
Modify your code like the next one and you'll be able to rename the whole file (even delete it!):
FileStream fileStream = File.Open(@"C:\temp\test1.txt", FileMode.Open, FileShare.ReadWrite | FileShare.Delete);
Console.ReadLine();