@@ -280,12 +280,7 @@ public static ICollection<PluginPair> ValidPluginsForQuery(Query query)
280280
281281 if ( ! NonGlobalPlugins . TryGetValue ( query . ActionKeyword , out var plugin ) )
282282 {
283- return GlobalPlugins . Where ( p => ! PluginModified ( p . Metadata . ID ) ) . ToList ( ) ;
284- }
285-
286- if ( API . PluginModified ( plugin . Metadata . ID ) )
287- {
288- return Array . Empty < PluginPair > ( ) ;
283+ return GlobalPlugins . ToList ( ) ;
289284 }
290285
291286 return new List < PluginPair >
@@ -296,7 +291,7 @@ public static ICollection<PluginPair> ValidPluginsForQuery(Query query)
296291
297292 public static ICollection < PluginPair > ValidPluginsForHomeQuery ( )
298293 {
299- return _homePlugins . Where ( p => ! PluginModified ( p . Metadata . ID ) ) . ToList ( ) ;
294+ return _homePlugins . ToList ( ) ;
300295 }
301296
302297 public static async Task < List < Result > > QueryForPluginAsync ( PluginPair pair , Query query , CancellationToken token )
@@ -503,201 +498,5 @@ public static void RemoveActionKeyword(string id, string oldActionkeyword)
503498 plugin . Metadata . ActionKeyword = string . Empty ;
504499 }
505500 }
506-
507- private static string GetContainingFolderPathAfterUnzip ( string unzippedParentFolderPath )
508- {
509- var unzippedFolderCount = Directory . GetDirectories ( unzippedParentFolderPath ) . Length ;
510- var unzippedFilesCount = Directory . GetFiles ( unzippedParentFolderPath ) . Length ;
511-
512- // adjust path depending on how the plugin is zipped up
513- // the recommended should be to zip up the folder not the contents
514- if ( unzippedFolderCount == 1 && unzippedFilesCount == 0 )
515- // folder is zipped up, unzipped plugin directory structure: tempPath/unzippedParentPluginFolder/pluginFolderName/
516- return Directory . GetDirectories ( unzippedParentFolderPath ) [ 0 ] ;
517-
518- if ( unzippedFilesCount > 1 )
519- // content is zipped up, unzipped plugin directory structure: tempPath/unzippedParentPluginFolder/
520- return unzippedParentFolderPath ;
521-
522- return string . Empty ;
523- }
524-
525- private static bool SameOrLesserPluginVersionExists ( string metadataPath )
526- {
527- var newMetadata = JsonSerializer . Deserialize < PluginMetadata > ( File . ReadAllText ( metadataPath ) ) ;
528- return AllPlugins . Any ( x => x . Metadata . ID == newMetadata . ID
529- && newMetadata . Version . CompareTo ( x . Metadata . Version ) <= 0 ) ;
530- }
531-
532- #region Public functions
533-
534- public static bool PluginModified ( string id )
535- {
536- return _modifiedPlugins . Contains ( id ) ;
537- }
538-
539- public static async Task UpdatePluginAsync ( PluginMetadata existingVersion , UserPlugin newVersion , string zipFilePath )
540- {
541- InstallPlugin ( newVersion , zipFilePath , checkModified : false ) ;
542- await UninstallPluginAsync ( existingVersion , removePluginFromSettings : false , removePluginSettings : false , checkModified : false ) ;
543- _modifiedPlugins . Add ( existingVersion . ID ) ;
544- }
545-
546- public static void InstallPlugin ( UserPlugin plugin , string zipFilePath )
547- {
548- InstallPlugin ( plugin , zipFilePath , checkModified : true ) ;
549- }
550-
551- public static async Task UninstallPluginAsync ( PluginMetadata plugin , bool removePluginSettings = false )
552- {
553- await UninstallPluginAsync ( plugin , removePluginFromSettings : true , removePluginSettings : removePluginSettings , checkModified : true ) ;
554- }
555-
556- #endregion
557-
558- #region Internal functions
559-
560- internal static void InstallPlugin ( UserPlugin plugin , string zipFilePath , bool checkModified )
561- {
562- if ( checkModified && PluginModified ( plugin . ID ) )
563- {
564- // Distinguish exception from installing same or less version
565- throw new ArgumentException ( $ "Plugin { plugin . Name } { plugin . ID } has been modified.", nameof ( plugin ) ) ;
566- }
567-
568- // Unzip plugin files to temp folder
569- var tempFolderPluginPath = Path . Combine ( Path . GetTempPath ( ) , Guid . NewGuid ( ) . ToString ( ) ) ;
570- System . IO . Compression . ZipFile . ExtractToDirectory ( zipFilePath , tempFolderPluginPath ) ;
571-
572- if ( ! plugin . IsFromLocalInstallPath )
573- File . Delete ( zipFilePath ) ;
574-
575- var pluginFolderPath = GetContainingFolderPathAfterUnzip ( tempFolderPluginPath ) ;
576-
577- var metadataJsonFilePath = string . Empty ;
578- if ( File . Exists ( Path . Combine ( pluginFolderPath , Constant . PluginMetadataFileName ) ) )
579- metadataJsonFilePath = Path . Combine ( pluginFolderPath , Constant . PluginMetadataFileName ) ;
580-
581- if ( string . IsNullOrEmpty ( metadataJsonFilePath ) || string . IsNullOrEmpty ( pluginFolderPath ) )
582- {
583- throw new FileNotFoundException ( $ "Unable to find plugin.json from the extracted zip file, or this path { pluginFolderPath } does not exist") ;
584- }
585-
586- if ( SameOrLesserPluginVersionExists ( metadataJsonFilePath ) )
587- {
588- throw new InvalidOperationException ( $ "A plugin with the same ID and version already exists, or the version is greater than this downloaded plugin { plugin . Name } ") ;
589- }
590-
591- var folderName = string . IsNullOrEmpty ( plugin . Version ) ? $ "{ plugin . Name } -{ Guid . NewGuid ( ) } " : $ "{ plugin . Name } -{ plugin . Version } ";
592-
593- var defaultPluginIDs = new List < string >
594- {
595- "0ECADE17459B49F587BF81DC3A125110" , // BrowserBookmark
596- "CEA0FDFC6D3B4085823D60DC76F28855" , // Calculator
597- "572be03c74c642baae319fc283e561a8" , // Explorer
598- "6A122269676E40EB86EB543B945932B9" , // PluginIndicator
599- "b64d0a79-329a-48b0-b53f-d658318a1bf6" , // ProcessKiller
600- "791FC278BA414111B8D1886DFE447410" , // Program
601- "D409510CD0D2481F853690A07E6DC426" , // Shell
602- "CEA08895D2544B019B2E9C5009600DF4" , // Sys
603- "0308FD86DE0A4DEE8D62B9B535370992" , // URL
604- "5043CETYU6A748679OPA02D27D99677A" // WindowsSettings
605- } ;
606-
607- // Treat default plugin differently, it needs to be removable along with each flow release
608- var installDirectory = ! defaultPluginIDs . Any ( x => x == plugin . ID )
609- ? DataLocation . PluginsDirectory
610- : Constant . PreinstalledDirectory ;
611-
612- var newPluginPath = Path . Combine ( installDirectory , folderName ) ;
613-
614- FilesFolders . CopyAll ( pluginFolderPath , newPluginPath , ( s ) => API . ShowMsgBox ( s ) ) ;
615-
616- try
617- {
618- if ( Directory . Exists ( tempFolderPluginPath ) )
619- Directory . Delete ( tempFolderPluginPath , true ) ;
620- }
621- catch ( Exception e )
622- {
623- API . LogException ( ClassName , $ "Failed to delete temp folder { tempFolderPluginPath } ", e ) ;
624- }
625-
626- if ( checkModified )
627- {
628- _modifiedPlugins . Add ( plugin . ID ) ;
629- }
630- }
631-
632- internal static async Task UninstallPluginAsync ( PluginMetadata plugin , bool removePluginFromSettings , bool removePluginSettings , bool checkModified )
633- {
634- if ( checkModified && PluginModified ( plugin . ID ) )
635- {
636- throw new ArgumentException ( $ "Plugin { plugin . Name } has been modified") ;
637- }
638-
639- if ( removePluginSettings || removePluginFromSettings )
640- {
641- // If we want to remove plugin from AllPlugins,
642- // we need to dispose them so that they can release file handles
643- // which can help FL to delete the plugin settings & cache folders successfully
644- var pluginPairs = AllPlugins . FindAll ( p => p . Metadata . ID == plugin . ID ) ;
645- foreach ( var pluginPair in pluginPairs )
646- {
647- await DisposePluginAsync ( pluginPair ) ;
648- }
649- }
650-
651- if ( removePluginSettings )
652- {
653- // For dotnet plugins, we need to remove their PluginJsonStorage and PluginBinaryStorage instances
654- if ( AllowedLanguage . IsDotNet ( plugin . Language ) && API is IRemovable removable )
655- {
656- removable . RemovePluginSettings ( plugin . AssemblyName ) ;
657- removable . RemovePluginCaches ( plugin . PluginCacheDirectoryPath ) ;
658- }
659-
660- try
661- {
662- var pluginSettingsDirectory = plugin . PluginSettingsDirectoryPath ;
663- if ( Directory . Exists ( pluginSettingsDirectory ) )
664- Directory . Delete ( pluginSettingsDirectory , true ) ;
665- }
666- catch ( Exception e )
667- {
668- API . LogException ( ClassName , $ "Failed to delete plugin settings folder for { plugin . Name } ", e ) ;
669- API . ShowMsg ( API . GetTranslation ( "failedToRemovePluginSettingsTitle" ) ,
670- string . Format ( API . GetTranslation ( "failedToRemovePluginSettingsMessage" ) , plugin . Name ) ) ;
671- }
672- }
673-
674- if ( removePluginFromSettings )
675- {
676- try
677- {
678- var pluginCacheDirectory = plugin . PluginCacheDirectoryPath ;
679- if ( Directory . Exists ( pluginCacheDirectory ) )
680- Directory . Delete ( pluginCacheDirectory , true ) ;
681- }
682- catch ( Exception e )
683- {
684- API . LogException ( ClassName , $ "Failed to delete plugin cache folder for { plugin . Name } ", e ) ;
685- API . ShowMsg ( API . GetTranslation ( "failedToRemovePluginCacheTitle" ) ,
686- string . Format ( API . GetTranslation ( "failedToRemovePluginCacheMessage" ) , plugin . Name ) ) ;
687- }
688- Settings . RemovePluginSettings ( plugin . ID ) ;
689- AllPlugins . RemoveAll ( p => p . Metadata . ID == plugin . ID ) ;
690- }
691-
692- // Marked for deletion. Will be deleted on next start up
693- using var _ = File . CreateText ( Path . Combine ( plugin . PluginDirectory , "NeedDelete.txt" ) ) ;
694-
695- if ( checkModified )
696- {
697- _modifiedPlugins . Add ( plugin . ID ) ;
698- }
699- }
700-
701- #endregion
702501 }
703502}
0 commit comments