1- using Flow . Launcher . Infrastructure . Logger ;
2- using Flow . Launcher . Infrastructure . UserSettings ;
3- using Flow . Launcher . Plugin ;
4- using Flow . Launcher . Plugin . SharedCommands ;
5- using System ;
1+ using System ;
62using System . Collections . Generic ;
3+ using System . IO ;
74using System . Linq ;
85using System . Windows ;
96using System . Windows . Forms ;
10- using Flow . Launcher . Core . Resource ;
117using CommunityToolkit . Mvvm . DependencyInjection ;
8+ using Flow . Launcher . Infrastructure . Logger ;
9+ using Flow . Launcher . Infrastructure . UserSettings ;
10+ using Flow . Launcher . Plugin ;
11+ using Flow . Launcher . Plugin . SharedCommands ;
1212
1313namespace Flow . Launcher . Core . ExternalPlugins . Environments
1414{
@@ -42,8 +42,11 @@ internal AbstractPluginEnvironment(List<PluginMetadata> pluginMetadataList, Plug
4242
4343 internal IEnumerable < PluginPair > Setup ( )
4444 {
45+ // If no plugin is using the language, return empty list
4546 if ( ! PluginMetadataList . Any ( o => o . Language . Equals ( Language , StringComparison . OrdinalIgnoreCase ) ) )
47+ {
4648 return new List < PluginPair > ( ) ;
49+ }
4750
4851 if ( ! string . IsNullOrEmpty ( PluginsSettingsFilePath ) && FilesFolders . FileExists ( PluginsSettingsFilePath ) )
4952 {
@@ -55,24 +58,55 @@ internal IEnumerable<PluginPair> Setup()
5558 }
5659
5760 var noRuntimeMessage = string . Format (
58- InternationalizationManager . Instance . GetTranslation ( "runtimePluginInstalledChooseRuntimePrompt" ) ,
61+ API . GetTranslation ( "runtimePluginInstalledChooseRuntimePrompt" ) ,
5962 Language ,
6063 EnvName ,
6164 Environment . NewLine
6265 ) ;
6366 if ( API . ShowMsgBox ( noRuntimeMessage , string . Empty , MessageBoxButton . YesNo ) == MessageBoxResult . No )
6467 {
65- var msg = string . Format ( InternationalizationManager . Instance . GetTranslation ( "runtimePluginChooseRuntimeExecutable" ) , EnvName ) ;
66- string selectedFile ;
68+ var msg = string . Format ( API . GetTranslation ( "runtimePluginChooseRuntimeExecutable" ) , EnvName ) ;
6769
68- selectedFile = GetFileFromDialog ( msg , FileDialogFilter ) ;
70+ var selectedFile = GetFileFromDialog ( msg , FileDialogFilter ) ;
6971
7072 if ( ! string . IsNullOrEmpty ( selectedFile ) )
73+ {
7174 PluginsSettingsFilePath = selectedFile ;
72-
75+ }
7376 // Nothing selected because user pressed cancel from the file dialog window
74- if ( string . IsNullOrEmpty ( selectedFile ) )
75- InstallEnvironment ( ) ;
77+ else
78+ {
79+ var forceDownloadMessage = string . Format (
80+ API . GetTranslation ( "runtimeExecutableInvalidChooseDownload" ) ,
81+ Language ,
82+ EnvName ,
83+ Environment . NewLine
84+ ) ;
85+
86+ // Let users select valid path or choose to download
87+ while ( string . IsNullOrEmpty ( selectedFile ) )
88+ {
89+ if ( API . ShowMsgBox ( forceDownloadMessage , string . Empty , MessageBoxButton . YesNo ) == MessageBoxResult . Yes )
90+ {
91+ // Continue select file
92+ selectedFile = GetFileFromDialog ( msg , FileDialogFilter ) ;
93+ }
94+ else
95+ {
96+ // User selected no, break the loop
97+ break ;
98+ }
99+ }
100+
101+ if ( ! string . IsNullOrEmpty ( selectedFile ) )
102+ {
103+ PluginsSettingsFilePath = selectedFile ;
104+ }
105+ else
106+ {
107+ InstallEnvironment ( ) ;
108+ }
109+ }
76110 }
77111 else
78112 {
@@ -85,7 +119,7 @@ internal IEnumerable<PluginPair> Setup()
85119 }
86120 else
87121 {
88- API . ShowMsgBox ( string . Format ( InternationalizationManager . Instance . GetTranslation ( "runtimePluginUnableToSetExecutablePath" ) , Language ) ) ;
122+ API . ShowMsgBox ( string . Format ( API . GetTranslation ( "runtimePluginUnableToSetExecutablePath" ) , Language ) ) ;
89123 Log . Error ( "PluginsLoader" ,
90124 $ "Not able to successfully set { EnvName } path, setting's plugin executable path variable is still an empty string.",
91125 $ "{ Language } Environment") ;
@@ -98,13 +132,11 @@ internal IEnumerable<PluginPair> Setup()
98132
99133 private void EnsureLatestInstalled ( string expectedPath , string currentPath , string installedDirPath )
100134 {
101- if ( expectedPath == currentPath )
102- return ;
135+ if ( expectedPath == currentPath ) return ;
103136
104137 FilesFolders . RemoveFolderIfExists ( installedDirPath , ( s ) => API . ShowMsgBox ( s ) ) ;
105138
106139 InstallEnvironment ( ) ;
107-
108140 }
109141
110142 internal abstract PluginPair CreatePluginPair ( string filePath , PluginMetadata metadata ) ;
@@ -116,13 +148,16 @@ private IEnumerable<PluginPair> SetPathForPluginPairs(string filePath, string la
116148 foreach ( var metadata in PluginMetadataList )
117149 {
118150 if ( metadata . Language . Equals ( languageToSet , StringComparison . OrdinalIgnoreCase ) )
151+ {
152+ metadata . AssemblyName = string . Empty ;
119153 pluginPairs . Add ( CreatePluginPair ( filePath , metadata ) ) ;
154+ }
120155 }
121156
122157 return pluginPairs ;
123158 }
124159
125- private string GetFileFromDialog ( string title , string filter = "" )
160+ private static string GetFileFromDialog ( string title , string filter = "" )
126161 {
127162 var dlg = new OpenFileDialog
128163 {
@@ -136,7 +171,6 @@ private string GetFileFromDialog(string title, string filter = "")
136171
137172 var result = dlg . ShowDialog ( ) ;
138173 return result == DialogResult . OK ? dlg . FileName : string . Empty ;
139-
140174 }
141175
142176 /// <summary>
@@ -179,31 +213,33 @@ public static void PreStartPluginExecutablePathUpdate(Settings settings)
179213 else
180214 {
181215 if ( IsUsingPortablePath ( settings . PluginSettings . PythonExecutablePath , DataLocation . PythonEnvironmentName ) )
216+ {
182217 settings . PluginSettings . PythonExecutablePath
183218 = GetUpdatedEnvironmentPath ( settings . PluginSettings . PythonExecutablePath ) ;
219+ }
184220
185221 if ( IsUsingPortablePath ( settings . PluginSettings . NodeExecutablePath , DataLocation . NodeEnvironmentName ) )
222+ {
186223 settings . PluginSettings . NodeExecutablePath
187224 = GetUpdatedEnvironmentPath ( settings . PluginSettings . NodeExecutablePath ) ;
225+ }
188226 }
189227 }
190228
191229 private static bool IsUsingPortablePath ( string filePath , string pluginEnvironmentName )
192230 {
193- if ( string . IsNullOrEmpty ( filePath ) )
194- return false ;
231+ if ( string . IsNullOrEmpty ( filePath ) ) return false ;
195232
196233 // DataLocation.PortableDataPath returns the current portable path, this determines if an out
197234 // of date path is also a portable path.
198- var portableAppEnvLocation = $ "UserData\\ { DataLocation . PluginEnvironments } \\ { pluginEnvironmentName } " ;
235+ var portableAppEnvLocation = Path . Combine ( "UserData" , DataLocation . PluginEnvironments , pluginEnvironmentName ) ;
199236
200237 return filePath . Contains ( portableAppEnvLocation ) ;
201238 }
202239
203240 private static bool IsUsingRoamingPath ( string filePath )
204241 {
205- if ( string . IsNullOrEmpty ( filePath ) )
206- return false ;
242+ if ( string . IsNullOrEmpty ( filePath ) ) return false ;
207243
208244 return filePath . StartsWith ( DataLocation . RoamingDataPath ) ;
209245 }
@@ -213,8 +249,8 @@ private static string GetUpdatedEnvironmentPath(string filePath)
213249 var index = filePath . IndexOf ( DataLocation . PluginEnvironments ) ;
214250
215251 // get the substring after "Environments" because we can not determine it dynamically
216- var ExecutablePathSubstring = filePath . Substring ( index + DataLocation . PluginEnvironments . Count ( ) ) ;
217- return $ "{ DataLocation . PluginEnvironmentsPath } { ExecutablePathSubstring } ";
252+ var executablePathSubstring = filePath [ ( index + DataLocation . PluginEnvironments . Length ) .. ] ;
253+ return $ "{ DataLocation . PluginEnvironmentsPath } { executablePathSubstring } ";
218254 }
219255 }
220256}
0 commit comments