Как освободить дескриптор через C#?
У меня есть приложение, которое НЕЗАКОННО открывает дескриптор на DLL / файл. В какой-то момент в приложении я хочу выпустить этот дескриптор. Как мне это сделать? Мое приложение в C#.
4 ответа
Используйте PInvoke, если у вас есть обработчик, который вы хотите закрыть
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
Что именно вы пытаетесь сделать? Если вы хотите загрузить сборку, чтобы сделать что-то с этим, а затем выгрузить ее полностью, вам нужно положиться на создание нового домена приложения.
public static void Main(string[] args)
{
AppDomain appDomain = AppDomain.CreateDomain("NewAppDomain");
appDomain.DoCallBack(new CrossAppDomainDelegate(AsmLoad));
// At this point, your assembly is locked, you can't delete
AppDomain.Unload(appDomain);
Console.WriteLine("AppDomain unloaded");
//You've completely unloaded your assembly. Now if you want, you can delete the same
}
public static void AsmLoad()
{
Assembly assembly = Assembly.LoadFrom(@"c:\Yourassembly.dll");
//Loaded to the new app domain. You can do some stuff here
Console.WriteLine("Assembly loaded in {0}",AppDomain.CurrentDomain.FriendlyName);
}
Посмотрите на этот пост больше, http://blogs.msdn.com/suzcook/archive/2003/07/08/57211.aspx
Или, если вас беспокоит только блокировка файла, вы можете использовать теневое копирование. Это сделает копию файла на диске и загрузит его из нового места. Исходный файл не будет заблокирован этой загрузкой. Чтобы сделать это, установите AppDomainSetup.ShadowCopyFiles в "true" при создании AppDomain или установите AppDomain.ShadowCopyFiles в "true" после того, как он уже был создан.
Просто используйте метод Dispose или Close класса, который открыл дескриптор.
Я не знаю простой способ. Чрезмерная неявная блокировка файлов - это то, что мне всегда не нравилось в Windows.
Если вам нужно заменить файл, MoveFileEx может сделать это при следующей загрузке. Вы будете использовать его, чтобы переименовать или удалить оригинал, а затем переименовать что-то еще на свое место. http://msdn.microsoft.com/en-us/library/aa365240(VS.85).aspx http://www.pinvoke.net/default.aspx/kernel32/MoveFileEx.html
Если вы не хотите связываться с API напрямую, в пакете SysInternals есть MoveFile, который делает то же самое: http://technet.microsoft.com/en-us/sysinternals/bb897556.aspx
Или вы можете иметь другую программу для доступа к файлу, когда ваша программа не запущена.
Есть способы получить список дескрипторов для каждого процесса, если вы действительно хотите попытаться закрыть дескриптор, что, скорее всего, приведет к краху вашей программы, если.NET попытается получить к нему доступ снова. Это не красиво, и пример C++: http://www.codeguru.com/forum/showthread.php?t=176997