@@ -72,15 +72,20 @@ public static async ValueTask DisposePluginsAsync()
7272 {
7373 foreach ( var pluginPair in AllPlugins )
7474 {
75- switch ( pluginPair . Plugin )
76- {
77- case IDisposable disposable :
78- disposable . Dispose ( ) ;
79- break ;
80- case IAsyncDisposable asyncDisposable :
81- await asyncDisposable . DisposeAsync ( ) ;
82- break ;
83- }
75+ await DisposePluginAsync ( pluginPair ) ;
76+ }
77+ }
78+
79+ private static async Task DisposePluginAsync ( PluginPair pluginPair )
80+ {
81+ switch ( pluginPair . Plugin )
82+ {
83+ case IDisposable disposable :
84+ disposable . Dispose ( ) ;
85+ break ;
86+ case IAsyncDisposable asyncDisposable :
87+ await asyncDisposable . DisposeAsync ( ) ;
88+ break ;
8489 }
8590 }
8691
@@ -565,13 +570,25 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
565570 }
566571 }
567572
568- internal static void UninstallPlugin ( PluginMetadata plugin , bool removePluginFromSettings , bool removePluginSettings , bool checkModified )
573+ internal static async void UninstallPlugin ( PluginMetadata plugin , bool removePluginFromSettings , bool removePluginSettings , bool checkModified )
569574 {
570575 if ( checkModified && PluginModified ( plugin . ID ) )
571576 {
572577 throw new ArgumentException ( $ "Plugin { plugin . Name } has been modified") ;
573578 }
574579
580+ if ( removePluginFromSettings )
581+ {
582+ // If we want to remove plugin from AllPlugins,
583+ // we need to dispose them so that they can release file handles
584+ // which can help FL to delete the plugin settings & cache folders successfully
585+ var pluginPairs = AllPlugins . FindAll ( p => p . Metadata . ID == plugin . ID ) ;
586+ foreach ( var pluginPair in pluginPairs )
587+ {
588+ await DisposePluginAsync ( pluginPair ) ;
589+ }
590+ }
591+
575592 if ( removePluginSettings )
576593 {
577594 // For dotnet plugins, we need to remove their PluginJsonStorage instance
0 commit comments