@@ -72,15 +72,20 @@ public static async ValueTask DisposePluginsAsync()
72
72
{
73
73
foreach ( var pluginPair in AllPlugins )
74
74
{
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 ;
84
89
}
85
90
}
86
91
@@ -565,13 +570,25 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c
565
570
}
566
571
}
567
572
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 )
569
574
{
570
575
if ( checkModified && PluginModified ( plugin . ID ) )
571
576
{
572
577
throw new ArgumentException ( $ "Plugin { plugin . Name } has been modified") ;
573
578
}
574
579
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
+
575
592
if ( removePluginSettings )
576
593
{
577
594
// For dotnet plugins, we need to remove their PluginJsonStorage instance
0 commit comments