Comment libérer une poignée via C #?
-
22-07-2019 - |
Question
J'ai une application qui ouvre implicitement un handle sur une dll / fichier. À un moment donné de l'application, je souhaite libérer ce descripteur. Comment puis-je le faire? Mon application est en C #.
La solution
utilisez PInvoke si vous souhaitez fermer un gestionnaire
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
Autres conseils
Qu'est-ce que vous essayez exactement de faire? Si vous souhaitez charger un assemblage pour le faire, puis le décharger complètement, vous devez vous fier à la création d'un nouveau domaine d'applications.
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);
}
Consultez cet article pour en savoir plus, http: //blogs.msdn.com/suzcook/archive/2003/07/08/57211.aspx
Ou, si vous ne vous inquiétez que de en gardant le fichier verrouillé, vous pouvez utiliser copie d'ombre. Cela fera une copie du fichier sur le disque et le charger à partir de le nouvel emplacement. Le fichier d'origine ne sera pas verrouillé par cette charge. À fais ça, place AppDomainSetup.ShadowCopyFiles à " true " lors de la création de l'AppDomain ou définir AppDomain.ShadowCopyFiles sur true après sa création.
Utilisez simplement la méthode Dispose ou Close de la classe qui a ouvert le descripteur.
Je ne connais pas de solution de facilité. Le verrouillage implicite excessif de fichiers est quelque chose que j'ai toujours détesté à propos de Windows.
Si vous devez remplacer le fichier, MoveFileEx peut le faire au prochain démarrage. Vous l'utiliseriez pour renommer ou supprimer l'original, puis renommer quelque chose d'autre à sa place. http://msdn.microsoft.com/en-us /library/aa365240(VS.85).aspx http://www.pinvoke.net/default.aspx/kernel32/MoveFileEx. html
Si vous ne voulez pas manipuler directement l'API, MoveFile de la suite SysInternals fait de même: http://technet.microsoft.com/en-us/sysinternals/bb897556.aspx
Vous pouvez également faire en sorte qu'un autre programme accède au fichier lorsque votre programme n'est pas en cours d'exécution.
Il existe des moyens d'obtenir une liste de descripteurs par processus, si vous souhaitez réellement essayer de fermer le descripteur, ce qui entraînerait probablement le blocage de votre programme si .NET tente à nouveau d'y accéder. Ce n'est pas joli, et l'exemple est C ++: http://www.codeguru.com/forum/showthread.php?t= 176997