mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
commit
620ed4afea
19 changed files with 350 additions and 112 deletions
|
|
@ -55,6 +55,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Droplex" Version="1.3.1" />
|
||||
<PackageReference Include="FSharp.Core" Version="4.7.1" />
|
||||
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.1.3" />
|
||||
<PackageReference Include="squirrel.windows" Version="1.5.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ using System.Threading.Tasks;
|
|||
using System.Windows.Forms;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
using Flow.Launcher.Plugin;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.IO;
|
||||
|
||||
namespace Flow.Launcher.Core.Plugin
|
||||
{
|
||||
|
|
@ -33,9 +35,11 @@ namespace Flow.Launcher.Core.Plugin
|
|||
protected abstract string ExecuteCallback(JsonRPCRequestModel rpcRequest);
|
||||
protected abstract string ExecuteContextMenu(Result selectedResult);
|
||||
|
||||
private static readonly RecyclableMemoryStreamManager BufferManager = new();
|
||||
|
||||
public List<Result> LoadContextMenus(Result selectedResult)
|
||||
{
|
||||
string output = ExecuteContextMenu(selectedResult);
|
||||
var output = ExecuteContextMenu(selectedResult);
|
||||
try
|
||||
{
|
||||
return DeserializedResult(output);
|
||||
|
|
@ -61,12 +65,23 @@ namespace Flow.Launcher.Core.Plugin
|
|||
{
|
||||
if (output == Stream.Null) return null;
|
||||
|
||||
var queryResponseModel = await
|
||||
JsonSerializer.DeserializeAsync<JsonRPCQueryResponseModel>(output, options);
|
||||
try
|
||||
{
|
||||
var queryResponseModel =
|
||||
await JsonSerializer.DeserializeAsync<JsonRPCQueryResponseModel>(output, options);
|
||||
|
||||
await output.DisposeAsync();
|
||||
|
||||
return ParseResults(queryResponseModel);
|
||||
return ParseResults(queryResponseModel);
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
Log.Exception(GetType().FullName, "Unexpected Json Input", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await output.DisposeAsync();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Result> DeserializedResult(string output)
|
||||
|
|
@ -81,7 +96,6 @@ namespace Flow.Launcher.Core.Plugin
|
|||
|
||||
private List<Result> ParseResults(JsonRPCQueryResponseModel queryResponseModel)
|
||||
{
|
||||
var results = new List<Result>();
|
||||
if (queryResponseModel.Result == null) return null;
|
||||
|
||||
if (!string.IsNullOrEmpty(queryResponseModel.DebugMessage))
|
||||
|
|
@ -89,7 +103,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
context.API.ShowMsg(queryResponseModel.DebugMessage);
|
||||
}
|
||||
|
||||
foreach (JsonRPCResult result in queryResponseModel.Result)
|
||||
foreach (var result in queryResponseModel.Result)
|
||||
{
|
||||
result.Action = c =>
|
||||
{
|
||||
|
|
@ -114,7 +128,8 @@ namespace Flow.Launcher.Core.Plugin
|
|||
return !result.JsonRPCAction.DontHideAfterAction;
|
||||
}
|
||||
|
||||
var jsonRpcRequestModel = JsonSerializer.Deserialize<JsonRPCRequestModel>(actionResponse, options);
|
||||
var jsonRpcRequestModel =
|
||||
JsonSerializer.Deserialize<JsonRPCRequestModel>(actionResponse, options);
|
||||
|
||||
if (jsonRpcRequestModel?.Method?.StartsWith("Flow.Launcher.") ?? false)
|
||||
{
|
||||
|
|
@ -125,9 +140,12 @@ namespace Flow.Launcher.Core.Plugin
|
|||
|
||||
return !result.JsonRPCAction.DontHideAfterAction;
|
||||
};
|
||||
results.Add(result);
|
||||
}
|
||||
|
||||
var results = new List<Result>();
|
||||
|
||||
results.AddRange(queryResponseModel.Result);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
|
@ -217,16 +235,42 @@ namespace Flow.Launcher.Core.Plugin
|
|||
|
||||
protected async Task<Stream> ExecuteAsync(ProcessStartInfo startInfo, CancellationToken token = default)
|
||||
{
|
||||
Process process = null;
|
||||
bool disposed = false;
|
||||
try
|
||||
{
|
||||
using var process = Process.Start(startInfo);
|
||||
process = Process.Start(startInfo);
|
||||
if (process == null)
|
||||
{
|
||||
Log.Error("|JsonRPCPlugin.ExecuteAsync|Can't start new process");
|
||||
return Stream.Null;
|
||||
}
|
||||
|
||||
var result = process.StandardOutput.BaseStream;
|
||||
await using var source = process.StandardOutput.BaseStream;
|
||||
|
||||
var buffer = BufferManager.GetStream();
|
||||
|
||||
token.Register(() =>
|
||||
{
|
||||
// ReSharper disable once AccessToModifiedClosure
|
||||
// Manually Check whether disposed
|
||||
if (!disposed && !process.HasExited)
|
||||
process.Kill();
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
// token expire won't instantly trigger the exception,
|
||||
// manually kill process at before
|
||||
await source.CopyToAsync(buffer, token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
await buffer.DisposeAsync();
|
||||
return Stream.Null;
|
||||
}
|
||||
|
||||
buffer.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
|
|
@ -245,7 +289,7 @@ namespace Flow.Launcher.Core.Plugin
|
|||
return Stream.Null;
|
||||
}
|
||||
|
||||
return result;
|
||||
return buffer;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -254,15 +298,24 @@ namespace Flow.Launcher.Core.Plugin
|
|||
e);
|
||||
return Stream.Null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
process?.Dispose();
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
|
||||
{
|
||||
var output = await ExecuteQueryAsync(query, token);
|
||||
try
|
||||
{
|
||||
var output = await ExecuteQueryAsync(query, token);
|
||||
return await DeserializedResultAsync(output);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Exception($"|JsonRPCPlugin.Query|Exception when query <{query}>", e);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ namespace Flow.Launcher
|
|||
|
||||
Http.API = API;
|
||||
Http.Proxy = _settings.Proxy;
|
||||
|
||||
|
||||
await PluginManager.InitializePlugins(API);
|
||||
var window = new MainWindow(_settings, _mainVM);
|
||||
|
||||
|
|
@ -99,6 +99,8 @@ namespace Flow.Launcher
|
|||
AutoStartup();
|
||||
AutoUpdates();
|
||||
|
||||
API.SaveAppAllSettings();
|
||||
|
||||
_mainVM.MainWindowVisibility = _settings.HideOnStartup ? Visibility.Hidden : Visibility.Visible;
|
||||
Log.Info("|App.OnStartup|End Flow Launcher startup ---------------------------------------------------- ");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -31,12 +31,15 @@
|
|||
<system:String x:Key="ignoreHotkeysOnFullscreen">Ignorovať klávesové skratky v režime na celú obrazovku</system:String>
|
||||
<system:String x:Key="pythonDirectory">Priečinok s Pythonom</system:String>
|
||||
<system:String x:Key="autoUpdates">Automatická aktualizácia</system:String>
|
||||
<system:String x:Key="autoHideScrollBar">Automaticky skryť posuvník</system:String>
|
||||
<system:String x:Key="autoHideScrollBarToolTip">Automaticky skrývať posuvník v okne nastavení a zobraziť ho, keď naň prejdete myšou</system:String>
|
||||
<system:String x:Key="selectPythonDirectory">Vybrať</system:String>
|
||||
<system:String x:Key="hideOnStartup">Schovať Flow Launcher po spustení</system:String>
|
||||
<system:String x:Key="hideNotifyIcon">Schovať ikonu z oblasti oznámení</system:String>
|
||||
<system:String x:Key="querySearchPrecision">Presnosť vyhľadávania</system:String>
|
||||
<system:String x:Key="ShouldUsePinyin">Použiť Pinyin</system:String>
|
||||
<system:String x:Key="ShouldUsePinyinToolTip">Umožňuje vyhľadávanie pomocou Pinyin. Pinyin je štandardný systém romanizovaného pravopisu pre transliteráciu čínštiny</system:String>
|
||||
<system:String x:Key="shadowEffectNotAllowed">Efekt tieňa nie je povolený, kým má aktuálny motív povolený efekt rozostrenia</system:String>
|
||||
|
||||
<!--Setting Plugin-->
|
||||
<system:String x:Key="plugin">Plugin</system:String>
|
||||
|
|
@ -48,6 +51,7 @@
|
|||
<system:String x:Key="newActionKeyword">Nová akcia skratky:</system:String>
|
||||
<system:String x:Key="currentPriority">Aktuálna priorita:</system:String>
|
||||
<system:String x:Key="newPriority">Nová priorita:</system:String>
|
||||
<system:String x:Key="priority">Priorita:</system:String>
|
||||
<system:String x:Key="pluginDirectory">Priečinok s pluginmi</system:String>
|
||||
<system:String x:Key="author">Autor</system:String>
|
||||
<system:String x:Key="plugin_init_time">Príprava:</system:String>
|
||||
|
|
@ -70,6 +74,7 @@
|
|||
<system:String x:Key="openResultModifiers">Modifikáčné klávesy na otvorenie výsledkov</system:String>
|
||||
<system:String x:Key="showOpenResultHotkey">Zobraziť klávesovú skratku</system:String>
|
||||
<system:String x:Key="customQueryHotkey">Vlastná klávesová skratka na vyhľadávanie</system:String>
|
||||
<system:String x:Key="customQuery">Dopyt</system:String>
|
||||
<system:String x:Key="delete">Odstrániť</system:String>
|
||||
<system:String x:Key="edit">Upraviť</system:String>
|
||||
<system:String x:Key="add">Pridať</system:String>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Window x:Class="Flow.Launcher.MainWindow"
|
||||
<Window x:Class="Flow.Launcher.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:flowlauncher="clr-namespace:Flow.Launcher"
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
</ContextMenu>
|
||||
</TextBox.ContextMenu>
|
||||
</TextBox>
|
||||
<svgc:SvgControl Source="{Binding Image}" HorizontalAlignment="Right" Width="48" Height="48"
|
||||
<svgc:SvgControl Source="{Binding Image}" HorizontalAlignment="Right" Width="42" Height="42"
|
||||
Background="Transparent"/>
|
||||
</Grid>
|
||||
<Line x:Name="ProgressBar" HorizontalAlignment="Right"
|
||||
|
|
|
|||
|
|
@ -77,54 +77,53 @@ namespace Flow.Launcher
|
|||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(MainViewModel.MainWindowVisibility):
|
||||
{
|
||||
if (_viewModel.MainWindowVisibility == Visibility.Visible)
|
||||
{
|
||||
Activate();
|
||||
QueryTextBox.Focus();
|
||||
UpdatePosition();
|
||||
_settings.ActivateTimes++;
|
||||
if (!_viewModel.LastQuerySelected)
|
||||
if (_viewModel.MainWindowVisibility == Visibility.Visible)
|
||||
{
|
||||
QueryTextBox.SelectAll();
|
||||
_viewModel.LastQuerySelected = true;
|
||||
Activate();
|
||||
QueryTextBox.Focus();
|
||||
UpdatePosition();
|
||||
_settings.ActivateTimes++;
|
||||
if (!_viewModel.LastQuerySelected)
|
||||
{
|
||||
QueryTextBox.SelectAll();
|
||||
_viewModel.LastQuerySelected = true;
|
||||
}
|
||||
|
||||
if (_viewModel.ProgressBarVisibility == Visibility.Visible && isProgressBarStoryboardPaused)
|
||||
{
|
||||
_progressBarStoryboard.Begin(ProgressBar, true);
|
||||
isProgressBarStoryboardPaused = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_viewModel.ProgressBarVisibility == Visibility.Visible && isProgressBarStoryboardPaused)
|
||||
else if (!isProgressBarStoryboardPaused)
|
||||
{
|
||||
_progressBarStoryboard.Begin(ProgressBar, true);
|
||||
isProgressBarStoryboardPaused = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isProgressBarStoryboardPaused)
|
||||
{
|
||||
_progressBarStoryboard.Stop(ProgressBar);
|
||||
isProgressBarStoryboardPaused = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case nameof(MainViewModel.ProgressBarVisibility):
|
||||
{
|
||||
Dispatcher.Invoke(async () =>
|
||||
{
|
||||
if (_viewModel.ProgressBarVisibility == Visibility.Hidden && !isProgressBarStoryboardPaused)
|
||||
{
|
||||
await Task.Delay(50);
|
||||
_progressBarStoryboard.Stop(ProgressBar);
|
||||
isProgressBarStoryboardPaused = true;
|
||||
}
|
||||
else if (_viewModel.MainWindowVisibility == Visibility.Visible &&
|
||||
isProgressBarStoryboardPaused)
|
||||
{
|
||||
_progressBarStoryboard.Begin(ProgressBar, true);
|
||||
isProgressBarStoryboardPaused = false;
|
||||
}
|
||||
}, System.Windows.Threading.DispatcherPriority.Render);
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nameof(MainViewModel.ProgressBarVisibility):
|
||||
{
|
||||
Dispatcher.Invoke(async () =>
|
||||
{
|
||||
if (_viewModel.ProgressBarVisibility == Visibility.Hidden && !isProgressBarStoryboardPaused)
|
||||
{
|
||||
await Task.Delay(50);
|
||||
_progressBarStoryboard.Stop(ProgressBar);
|
||||
isProgressBarStoryboardPaused = true;
|
||||
}
|
||||
else if (_viewModel.MainWindowVisibility == Visibility.Visible &&
|
||||
isProgressBarStoryboardPaused)
|
||||
{
|
||||
_progressBarStoryboard.Begin(ProgressBar, true);
|
||||
isProgressBarStoryboardPaused = false;
|
||||
}
|
||||
}, System.Windows.Threading.DispatcherPriority.Render);
|
||||
|
||||
break;
|
||||
}
|
||||
case nameof(MainViewModel.QueryTextCursorMovedToEnd):
|
||||
if (_viewModel.QueryTextCursorMovedToEnd)
|
||||
{
|
||||
|
|
@ -230,10 +229,10 @@ namespace Flow.Launcher
|
|||
{
|
||||
if (sender != null && e.OriginalSource != null)
|
||||
{
|
||||
var r = (ResultListBox) sender;
|
||||
var d = (DependencyObject) e.OriginalSource;
|
||||
var r = (ResultListBox)sender;
|
||||
var d = (DependencyObject)e.OriginalSource;
|
||||
var item = ItemsControl.ContainerFromElement(r, d) as ListBoxItem;
|
||||
var result = (ResultViewModel) item?.DataContext;
|
||||
var result = (ResultViewModel)item?.DataContext;
|
||||
if (result != null)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
<TabControl Height="auto" SelectedIndex="0">
|
||||
<TabItem Header="{DynamicResource general}">
|
||||
<ScrollViewer ui:ScrollViewerHelper.AutoHideScrollBars="{Binding AutoHideScrollBar, Mode=OneWay}" Margin="60,0,0,0">
|
||||
<StackPanel Orientation="Vertical" Margin="0,30,0,0">
|
||||
<StackPanel Orientation="Vertical" Margin="0,30,0,30">
|
||||
<ui:ToggleSwitch Margin="10" IsOn="{Binding PortableMode}">
|
||||
<TextBlock Text="{DynamicResource portableMode}" />
|
||||
</ui:ToggleSwitch>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@
|
|||
<system:String x:Key="plugin_explorer_deletefilefoldersuccess">Deletion successful</system:String>
|
||||
<system:String x:Key="plugin_explorer_deletefilefoldersuccess_detail">Successfully deleted the {0}</system:String>
|
||||
<system:String x:Key="plugin_explorer_globalActionKeywordInvalid">Assigning the global action keyword could bring up too many results during search. Please choose a specific action keyword</system:String>
|
||||
<system:String x:Key="plugin_explorer_windowsSearchServiceNotRunning">The required service for Windows Index Search does not appear to be running</system:String>
|
||||
<system:String x:Key="plugin_explorer_windowsSearchServiceFix">To fix this, start the Windows Search service. Select here to remove this warning</system:String>
|
||||
<system:String x:Key="plugin_explorer_alternative">The warning message has been switched off. As an alternative for searching files and folders, would you like to install Everything plugin?{0}{0}Select 'Yes' to install Everything plugin, or 'No' to return</system:String>
|
||||
<system:String x:Key="plugin_explorer_alternative_title">Explorer Alternative</system:String>
|
||||
|
||||
<!--Controls-->
|
||||
<system:String x:Key="plugin_explorer_delete">Delete</system:String>
|
||||
|
|
|
|||
66
Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml
Normal file
66
Plugins/Flow.Launcher.Plugin.Explorer/Languages/sk.xaml
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
|
||||
<!--Dialogues-->
|
||||
<system:String x:Key="plugin_explorer_make_selection_warning">Najprv vyberte položku</system:String>
|
||||
<system:String x:Key="plugin_explorer_select_folder_link_warning">Vyberte odkaz na priečinok</system:String>
|
||||
<system:String x:Key="plugin_explorer_delete_folder_link">Naozaj chcete odstrániť {0}?</system:String>
|
||||
<system:String x:Key="plugin_explorer_deletefilefolderconfirm">Naozaj chcete natrvalo odstrániť túto položku {0}?</system:String>
|
||||
<system:String x:Key="plugin_explorer_deletefilefoldersuccess">Odstránenie bolo úspešné</system:String>
|
||||
<system:String x:Key="plugin_explorer_deletefilefoldersuccess_detail">Úspešne odstránené {0}</system:String>
|
||||
<system:String x:Key="plugin_explorer_globalActionKeywordInvalid">Priradenie globálnej skratky akcie by mohlo počas vyhľadávania poskytnúť príliš veľa výsledkov. Vyberte si konkrétne kľúčové slovo akcie</system:String>
|
||||
<system:String x:Key="plugin_explorer_windowsSearchServiceNotRunning">Zdá sa, že požadovaná služba Windows Index Search nie je spustená</system:String>
|
||||
<system:String x:Key="plugin_explorer_windowsSearchServiceFix">Ak to chcete opraviť, spustite službu Windows Search. Ak chcete odstrániť toto upozornenie, kliknite sem</system:String>
|
||||
<system:String x:Key="plugin_explorer_alternative">Upozornenie bolo vypnuté. Chceli by ste ako alternatívu na vyhľadávanie súborov a priečinkov nainštalovať plugin Everything?{0}{0}Ak chcete nainštalovať plugin Everything, zvoľte 'Áno', pre návrat zvoľte 'Nie'</system:String>
|
||||
<system:String x:Key="plugin_explorer_alternative_title">Alternatíva pre Explorer</system:String>
|
||||
|
||||
<!--Controls-->
|
||||
<system:String x:Key="plugin_explorer_delete">Odstrániť</system:String>
|
||||
<system:String x:Key="plugin_explorer_edit">Upraviť</system:String>
|
||||
<system:String x:Key="plugin_explorer_add">Pridať</system:String>
|
||||
<system:String x:Key="plugin_explorer_manageactionkeywords_header">Upraviť skratku akcie</system:String>
|
||||
<system:String x:Key="plugin_explorer_quickaccesslinks_header">Odkazy Rýchleho prístupu</system:String>
|
||||
<system:String x:Key="plugin_explorer_indexsearchexcludedpaths_header">Vylúčené umiestnenia indexovania</system:String>
|
||||
<system:String x:Key="plugin_explorer_manageindexoptions">Možnosti indexovania</system:String>
|
||||
<system:String x:Key="plugin_explorer_actionkeywordview_search">Vyhľadávanie:</system:String>
|
||||
<system:String x:Key="plugin_explorer_actionkeywordview_pathsearch">Vyhľadávanie umiestnenia:</system:String>
|
||||
<system:String x:Key="plugin_explorer_actionkeywordview_filecontentsearch">Vyhľadávanie obsahu súborov:</system:String>
|
||||
<system:String x:Key="plugin_explorer_actionkeywordview_indexsearch">Vyhľadávanie v indexe:</system:String>
|
||||
<system:String x:Key="plugin_explorer_actionkeyword_current">Aktuálna skratka:</system:String>
|
||||
<system:String x:Key="plugin_explorer_actionkeyword_done">Hotovo</system:String>
|
||||
<system:String x:Key="plugin_explorer_actionkeyword_enabled">Povolené</system:String>
|
||||
<system:String x:Key="plugin_explorer_actionkeyword_enabled_tooltip">Ak je vypnuté, Flow túto možnosť vyhľadávania nevykoná a následne sa vráti späť na "*", aby sa uvoľnila skratka akcie.</system:String>
|
||||
|
||||
<!--Plugin Infos-->
|
||||
<system:String x:Key="plugin_explorer_plugin_name">Explorer</system:String>
|
||||
<system:String x:Key="plugin_explorer_plugin_description">Vyhľadáva a spravuje súbory a priečinky. Explorer používa indexovanie vyhľadávania vo Windowse</system:String>
|
||||
|
||||
<!--Context menu items-->
|
||||
<system:String x:Key="plugin_explorer_copypath">Kopírovať cestu</system:String>
|
||||
<system:String x:Key="plugin_explorer_copyfilefolder">Kopírovať</system:String>
|
||||
<system:String x:Key="plugin_explorer_deletefilefolder">Odstrániť</system:String>
|
||||
<system:String x:Key="plugin_explorer_path">Umiestnenie:</system:String>
|
||||
<system:String x:Key="plugin_explorer_deletefilefolder_subtitle">Odstrániť vybrané</system:String>
|
||||
<system:String x:Key="plugin_explorer_runasdifferentuser">Spustiť ako iný používateľ</system:String>
|
||||
<system:String x:Key="plugin_explorer_runasdifferentuser_subtitle">Spustí vybranú položku ako používateľ s iným kontom</system:String>
|
||||
<system:String x:Key="plugin_explorer_opencontainingfolder">Otvoriť umiestnenie priečinka</system:String>
|
||||
<system:String x:Key="plugin_explorer_opencontainingfolder_subtitle">Otvorí umiestnenie, ktoré obsahuje súbor alebo priečinok</system:String>
|
||||
<system:String x:Key="plugin_explorer_openwitheditor">Otvoriť editorom:</system:String>
|
||||
<system:String x:Key="plugin_explorer_excludefromindexsearch">Vylúčiť položku a jej podpriečinky z indexu vyhľadávania</system:String>
|
||||
<system:String x:Key="plugin_explorer_excludedfromindexsearch_msg">Vylúčiť z indexu vyhľadávania</system:String>
|
||||
<system:String x:Key="plugin_explorer_openindexingoptions">Otvoriť možnosti vyhľadávania vo Windowse</system:String>
|
||||
<system:String x:Key="plugin_explorer_openindexingoptions_subtitle">Správa indexovaných súborov a priečinkov</system:String>
|
||||
<system:String x:Key="plugin_explorer_openindexingoptions_errormsg">Nepodarilo sa otvoriť možnosti indexu vyhľadávania</system:String>
|
||||
<system:String x:Key="plugin_explorer_add_to_quickaccess_title">Pridať do Rýchleho prístupu</system:String>
|
||||
<system:String x:Key="plugin_explorer_add_to_quickaccess_subtitle">Pridať tento {0} do Rýchleho prístupu</system:String>
|
||||
<system:String x:Key="plugin_explorer_addfilefoldersuccess">Úspešne pridané</system:String>
|
||||
<system:String x:Key="plugin_explorer_addfilefoldersuccess_detail">Úspešne pridané do Rýchleho prístupu</system:String>
|
||||
<system:String x:Key="plugin_explorer_removefilefoldersuccess">Úspešne odstránené</system:String>
|
||||
<system:String x:Key="plugin_explorer_removefilefoldersuccess_detail">Úspešne odstránené z Rýchleho prístupu</system:String>
|
||||
<system:String x:Key="plugin_explorer_contextmenu_titletooltip">Pridať do Rýchleho prístupu, aby ho bolo možné otvoriť pomocou skratky akcie pluginu Explorer</system:String>
|
||||
<system:String x:Key="plugin_explorer_contextmenu_remove_titletooltip">Odstráni z Rýchleho prístupu</system:String>
|
||||
<system:String x:Key="plugin_explorer_remove_from_quickaccess_title">Odstrániť z Rýchleho prístupu</system:String>
|
||||
<system:String x:Key="plugin_explorer_remove_from_quickaccess_subtitle">Odstráni {0} z Rýchleho prístupu</system:String>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
|
@ -12,14 +12,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
{
|
||||
public class SearchManager
|
||||
{
|
||||
private readonly PluginInitContext context;
|
||||
internal static PluginInitContext Context;
|
||||
|
||||
private readonly Settings settings;
|
||||
internal static Settings Settings;
|
||||
|
||||
public SearchManager(Settings settings, PluginInitContext context)
|
||||
{
|
||||
this.context = context;
|
||||
this.settings = settings;
|
||||
Context = context;
|
||||
Settings = settings;
|
||||
}
|
||||
|
||||
private class PathEqualityComparator : IEqualityComparer<Result>
|
||||
|
|
@ -71,14 +71,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
|
||||
return allowedActionKeyword switch
|
||||
{
|
||||
Settings.ActionKeyword.SearchActionKeyword => settings.SearchActionKeywordEnabled &&
|
||||
keyword == settings.SearchActionKeyword,
|
||||
Settings.ActionKeyword.PathSearchActionKeyword => settings.PathSearchKeywordEnabled &&
|
||||
keyword == settings.PathSearchActionKeyword,
|
||||
Settings.ActionKeyword.SearchActionKeyword => Settings.SearchActionKeywordEnabled &&
|
||||
keyword == Settings.SearchActionKeyword,
|
||||
Settings.ActionKeyword.PathSearchActionKeyword => Settings.PathSearchKeywordEnabled &&
|
||||
keyword == Settings.PathSearchActionKeyword,
|
||||
Settings.ActionKeyword.FileContentSearchActionKeyword => keyword ==
|
||||
settings.FileContentSearchActionKeyword,
|
||||
Settings.ActionKeyword.IndexSearchActionKeyword => settings.IndexOnlySearchKeywordEnabled &&
|
||||
keyword == settings.IndexSearchActionKeyword
|
||||
Settings.FileContentSearchActionKeyword,
|
||||
Settings.ActionKeyword.IndexSearchActionKeyword => Settings.IndexOnlySearchKeywordEnabled &&
|
||||
keyword == Settings.IndexSearchActionKeyword
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -88,18 +88,18 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
|
||||
// This allows the user to type the assigned action keyword and only see the list of quick folder links
|
||||
if (string.IsNullOrEmpty(query.Search))
|
||||
return QuickAccess.AccessLinkListAll(query, settings.QuickAccessLinks);
|
||||
return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks);
|
||||
|
||||
var results = new HashSet<Result>(PathEqualityComparator.Instance);
|
||||
|
||||
var quickaccessLinks = QuickAccess.AccessLinkListMatched(query, settings.QuickAccessLinks);
|
||||
var quickaccessLinks = QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks);
|
||||
|
||||
results.UnionWith(quickaccessLinks);
|
||||
|
||||
var isEnvironmentVariable = EnvironmentVariables.IsEnvironmentVariableSearch(querySearch);
|
||||
|
||||
if (isEnvironmentVariable)
|
||||
return EnvironmentVariables.GetEnvironmentStringPathSuggestions(querySearch, query, context);
|
||||
return EnvironmentVariables.GetEnvironmentStringPathSuggestions(querySearch, query, Context);
|
||||
|
||||
// Query is a location path with a full environment variable, eg. %appdata%\somefolder\
|
||||
var isEnvironmentVariablePath = querySearch[1..].Contains("%\\");
|
||||
|
|
@ -136,22 +136,23 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
private async Task<List<Result>> WindowsIndexFileContentSearchAsync(Query query, string querySearchString,
|
||||
CancellationToken token)
|
||||
{
|
||||
var queryConstructor = new QueryConstructor(settings);
|
||||
var queryConstructor = new QueryConstructor(Settings);
|
||||
|
||||
if (string.IsNullOrEmpty(querySearchString))
|
||||
return new List<Result>();
|
||||
|
||||
return await IndexSearch.WindowsIndexSearchAsync(querySearchString,
|
||||
queryConstructor.CreateQueryHelper().ConnectionString,
|
||||
return await IndexSearch.WindowsIndexSearchAsync(
|
||||
querySearchString,
|
||||
queryConstructor.CreateQueryHelper(),
|
||||
queryConstructor.QueryForFileContentSearch,
|
||||
settings.IndexSearchExcludedSubdirectoryPaths,
|
||||
Settings.IndexSearchExcludedSubdirectoryPaths,
|
||||
query,
|
||||
token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public bool IsFileContentSearch(string actionKeyword)
|
||||
{
|
||||
return actionKeyword == settings.FileContentSearchActionKeyword;
|
||||
return actionKeyword == Settings.FileContentSearchActionKeyword;
|
||||
}
|
||||
|
||||
private List<Result> DirectoryInfoClassSearch(Query query, string querySearch, CancellationToken token)
|
||||
|
|
@ -176,12 +177,13 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
private async Task<List<Result>> WindowsIndexFilesAndFoldersSearchAsync(Query query, string querySearchString,
|
||||
CancellationToken token)
|
||||
{
|
||||
var queryConstructor = new QueryConstructor(settings);
|
||||
var queryConstructor = new QueryConstructor(Settings);
|
||||
|
||||
return await IndexSearch.WindowsIndexSearchAsync(querySearchString,
|
||||
queryConstructor.CreateQueryHelper().ConnectionString,
|
||||
return await IndexSearch.WindowsIndexSearchAsync(
|
||||
querySearchString,
|
||||
queryConstructor.CreateQueryHelper(),
|
||||
queryConstructor.QueryForAllFilesAndFolders,
|
||||
settings.IndexSearchExcludedSubdirectoryPaths,
|
||||
Settings.IndexSearchExcludedSubdirectoryPaths,
|
||||
query,
|
||||
token).ConfigureAwait(false);
|
||||
}
|
||||
|
|
@ -189,12 +191,13 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
private async Task<List<Result>> WindowsIndexTopLevelFolderSearchAsync(Query query, string path,
|
||||
CancellationToken token)
|
||||
{
|
||||
var queryConstructor = new QueryConstructor(settings);
|
||||
var queryConstructor = new QueryConstructor(Settings);
|
||||
|
||||
return await IndexSearch.WindowsIndexSearchAsync(path,
|
||||
queryConstructor.CreateQueryHelper().ConnectionString,
|
||||
return await IndexSearch.WindowsIndexSearchAsync(
|
||||
path,
|
||||
queryConstructor.CreateQueryHelper(),
|
||||
queryConstructor.QueryForTopLevelDirectorySearch,
|
||||
settings.IndexSearchExcludedSubdirectoryPaths,
|
||||
Settings.IndexSearchExcludedSubdirectoryPaths,
|
||||
query,
|
||||
token).ConfigureAwait(false);
|
||||
}
|
||||
|
|
@ -203,10 +206,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
|||
{
|
||||
var pathToDirectory = FilesFolders.ReturnPreviousDirectoryIfIncompleteString(locationPath);
|
||||
|
||||
if (!settings.UseWindowsIndexForDirectorySearch)
|
||||
if (!Settings.UseWindowsIndexForDirectorySearch)
|
||||
return false;
|
||||
|
||||
if (settings.IndexSearchExcludedSubdirectoryPaths
|
||||
if (Settings.IndexSearchExcludedSubdirectoryPaths
|
||||
.Any(x => FilesFolders.ReturnPreviousDirectoryIfIncompleteString(pathToDirectory)
|
||||
.StartsWith(x.Path, StringComparison.OrdinalIgnoreCase)))
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Data.OleDb;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
|
||||
{
|
||||
|
|
@ -84,22 +86,36 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
|
|||
return results;
|
||||
}
|
||||
|
||||
internal async static Task<List<Result>> WindowsIndexSearchAsync(string searchString, string connectionString,
|
||||
Func<string, string> constructQuery,
|
||||
List<AccessLink> exclusionList,
|
||||
Query query,
|
||||
CancellationToken token)
|
||||
internal async static Task<List<Result>> WindowsIndexSearchAsync(
|
||||
string searchString,
|
||||
CSearchQueryHelper queryHelper,
|
||||
Func<string, string> constructQuery,
|
||||
List<AccessLink> exclusionList,
|
||||
Query query,
|
||||
CancellationToken token)
|
||||
{
|
||||
var regexMatch = Regex.Match(searchString, reservedStringPattern);
|
||||
|
||||
if (regexMatch.Success)
|
||||
return new List<Result>();
|
||||
|
||||
try
|
||||
{
|
||||
var constructedQuery = constructQuery(searchString);
|
||||
|
||||
var constructedQuery = constructQuery(searchString);
|
||||
return RemoveResultsInExclusionList(
|
||||
await ExecuteWindowsIndexSearchAsync(constructedQuery, connectionString, query, token).ConfigureAwait(false),
|
||||
return RemoveResultsInExclusionList(
|
||||
await ExecuteWindowsIndexSearchAsync(constructedQuery, queryHelper.ConnectionString, query, token).ConfigureAwait(false),
|
||||
exclusionList,
|
||||
token);
|
||||
}
|
||||
catch (COMException)
|
||||
{
|
||||
// Occurs because the Windows Indexing (WSearch) is turned off in services and unable to be used by Explorer plugin
|
||||
if (!SearchManager.Settings.WarnWindowsSearchServiceOff)
|
||||
return new List<Result>();
|
||||
|
||||
return ResultForWindexSearchOff(query.RawQuery);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Result> RemoveResultsInExclusionList(List<Result> results, List<AccessLink> exclusionList, CancellationToken token)
|
||||
|
|
@ -137,9 +153,66 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
|
|||
|
||||
internal static bool PathIsIndexed(string path)
|
||||
{
|
||||
var csm = new CSearchManager();
|
||||
var indexManager = csm.GetCatalog("SystemIndex").GetCrawlScopeManager();
|
||||
return indexManager.IncludedInCrawlScope(path) > 0;
|
||||
try
|
||||
{
|
||||
var csm = new CSearchManager();
|
||||
var indexManager = csm.GetCatalog("SystemIndex").GetCrawlScopeManager();
|
||||
return indexManager.IncludedInCrawlScope(path) > 0;
|
||||
}
|
||||
catch(COMException)
|
||||
{
|
||||
// Occurs because the Windows Indexing (WSearch) is turned off in services and unable to be used by Explorer plugin
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Result> ResultForWindexSearchOff(string rawQuery)
|
||||
{
|
||||
var api = SearchManager.Context.API;
|
||||
|
||||
return new List<Result>
|
||||
{
|
||||
new Result
|
||||
{
|
||||
Title = api.GetTranslation("plugin_explorer_windowsSearchServiceNotRunning"),
|
||||
SubTitle = api.GetTranslation("plugin_explorer_windowsSearchServiceFix"),
|
||||
Action = c =>
|
||||
{
|
||||
SearchManager.Settings.WarnWindowsSearchServiceOff = false;
|
||||
|
||||
var pluginsManagerPlugin= api.GetAllPlugins().FirstOrDefault(x => x.Metadata.ID == "9f8f9b14-2518-4907-b211-35ab6290dee7");
|
||||
|
||||
var actionKeywordCount = pluginsManagerPlugin.Metadata.ActionKeywords.Count;
|
||||
|
||||
if (actionKeywordCount > 1)
|
||||
LogException("PluginsManager's action keyword has increased to more than 1, this does not allow for determining the " +
|
||||
"right action keyword. Explorer's code for managing Windows Search service not running exception needs to be updated",
|
||||
new InvalidOperationException());
|
||||
|
||||
if (MessageBox.Show(string.Format(api.GetTranslation("plugin_explorer_alternative"), Environment.NewLine),
|
||||
api.GetTranslation("plugin_explorer_alternative_title"),
|
||||
MessageBoxButton.YesNo) == MessageBoxResult.Yes
|
||||
&& actionKeywordCount == 1)
|
||||
{
|
||||
api.ChangeQuery(string.Format("{0} install everything", pluginsManagerPlugin.Metadata.ActionKeywords[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clears the warning message because same query string will not alter the displayed result list
|
||||
api.ChangeQuery(string.Empty);
|
||||
|
||||
api.ChangeQuery(rawQuery);
|
||||
}
|
||||
|
||||
var mainWindow = Application.Current.MainWindow;
|
||||
mainWindow.Visibility = Visibility.Visible;
|
||||
mainWindow.Focus();
|
||||
|
||||
return false;
|
||||
},
|
||||
IcoPath = Constants.ExplorerIconImagePath
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static void LogException(string message, Exception e)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Flow.Launcher.Plugin.Explorer.Search;
|
||||
using Flow.Launcher.Plugin.Explorer.Search;
|
||||
using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks;
|
||||
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
||||
using System;
|
||||
|
|
@ -33,6 +33,8 @@ namespace Flow.Launcher.Plugin.Explorer
|
|||
|
||||
public bool IndexOnlySearchKeywordEnabled { get; set; }
|
||||
|
||||
public bool WarnWindowsSearchServiceOff { get; set; } = true;
|
||||
|
||||
internal enum ActionKeyword
|
||||
{
|
||||
SearchActionKeyword,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
"Name": "Explorer",
|
||||
"Description": "Search and manage files and folders. Explorer utilises Windows Index Search",
|
||||
"Author": "Jeremy Wu",
|
||||
"Version": "1.8.0",
|
||||
"Version": "1.8.2",
|
||||
"Language": "csharp",
|
||||
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
|
||||
"ExecuteFileName": "Flow.Launcher.Plugin.Explorer.dll",
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ namespace Flow.Launcher.Plugin.PluginsManager
|
|||
|
||||
public List<Result> LoadContextMenus(Result selectedResult)
|
||||
{
|
||||
var pluginManifestInfo = selectedResult.ContextData as UserPlugin;
|
||||
if(selectedResult.ContextData is not UserPlugin pluginManifestInfo)
|
||||
return new List<Result>();
|
||||
|
||||
return new List<Result>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -269,7 +269,13 @@ namespace Flow.Launcher.Plugin.PluginsManager
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
ContextData =
|
||||
new UserPlugin
|
||||
{
|
||||
Website = x.PluginNewUserPlugin.Website,
|
||||
UrlSourceCode = x.PluginNewUserPlugin.UrlSourceCode
|
||||
}
|
||||
});
|
||||
|
||||
return Search(results, uninstallSearch);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
"Name": "Plugins Manager",
|
||||
"Description": "Management of installing, uninstalling or updating Flow Launcher plugins",
|
||||
"Author": "Jeremy Wu",
|
||||
"Version": "1.8.3",
|
||||
"Version": "1.8.4",
|
||||
"Language": "csharp",
|
||||
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
|
||||
"ExecuteFileName": "Flow.Launcher.Plugin.PluginsManager.dll",
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ Flow Launcher. Dedicated to make your workflow flow more seamlessly. Aimed at be
|
|||
|
||||
### Installation
|
||||
|
||||
| [Windows 7 and up installer](https://github.com/Flow-Launcher/Flow.Launcher/releases/latest) | `WinGet install "Flow Launcher"` |
|
||||
| -------------------------------------------------------------------------------------------- | -------------------------------- |
|
||||
| [Windows 7 and up installer](https://github.com/Flow-Launcher/Flow.Launcher/releases/latest) | [Portable](https://github.com/Flow-Launcher/Flow.Launcher/releases/latest/download/Flow-Launcher-Portable.zip) | `WinGet install "Flow Launcher"` |
|
||||
| --------------------------------- | --------------------------------- | --------------------------------- |
|
||||
|
||||
Windows may complain about security due to code not being signed, this will be completed at a later stage. If you downloaded from this repo, you are good to continue the set up.
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,13 @@ function Publish-Self-Contained ($p) {
|
|||
dotnet publish -c Release $csproj /p:PublishProfile=$profile
|
||||
}
|
||||
|
||||
function Publish-Portable ($outputLocation, $version) {
|
||||
|
||||
& $outputLocation\Flow-Launcher-v$v.exe --silent | Out-Null
|
||||
mkdir "$env:LocalAppData\FlowLauncher\app-$version\UserData"
|
||||
Compress-Archive -Path $env:LocalAppData\FlowLauncher -DestinationPath $outputLocation\Flow-Launcher-Portable.zip
|
||||
}
|
||||
|
||||
function Main {
|
||||
$p = Build-Path
|
||||
$v = Build-Version
|
||||
|
|
@ -123,6 +130,8 @@ function Main {
|
|||
$o = "$p\Output\Packages"
|
||||
Validate-Directory $o
|
||||
Pack-Squirrel-Installer $p $v $o
|
||||
|
||||
Publish-Portable $o $v
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
22
appveyor.yml
22
appveyor.yml
|
|
@ -1,4 +1,4 @@
|
|||
version: '1.8.0.{build}'
|
||||
version: '1.8.1.{build}'
|
||||
|
||||
init:
|
||||
- ps: |
|
||||
|
|
@ -36,6 +36,8 @@ artifacts:
|
|||
name: Plugin nupkg
|
||||
- path: 'Output\Packages\Flow-Launcher-*.exe'
|
||||
name: Squirrel Installer
|
||||
- path: Output\Packages\Flow-Launcher-Portable.zip
|
||||
name: Portable Version
|
||||
- path: 'Output\Packages\FlowLauncher-*-full.nupkg'
|
||||
name: Squirrel nupkg
|
||||
- path: 'Output\Packages\RELEASES'
|
||||
|
|
@ -47,13 +49,13 @@ deploy:
|
|||
api_key:
|
||||
secure: n80IeWR3pN81p0w4uXq4mO0TdTXoJSHHFL+yTB9YBJ0Wni2DjZGYwOFdaWzW4hRi
|
||||
on:
|
||||
branch: master
|
||||
APPVEYOR_REPO_TAG: true
|
||||
|
||||
- provider: GitHub
|
||||
release: v$(flowVersion)
|
||||
auth_token:
|
||||
secure: ij4UeXUYQBDJxn2YRAAhUOjklOGVKDB87Hn5J8tKIzj13yatoI7sLM666QDQFEgv
|
||||
artifact: Squirrel Installer, Squirrel nupkg, Squirrel RELEASES
|
||||
artifact: Squirrel Installer, Portable Version, Squirrel nupkg, Squirrel RELEASES
|
||||
draft: true
|
||||
force_update: true
|
||||
on:
|
||||
|
|
@ -63,7 +65,19 @@ deploy:
|
|||
release: v$(flowVersion)
|
||||
auth_token:
|
||||
secure: ij4UeXUYQBDJxn2YRAAhUOjklOGVKDB87Hn5J8tKIzj13yatoI7sLM666QDQFEgv
|
||||
artifact: Squirrel Installer, Squirrel nupkg, Squirrel RELEASES
|
||||
artifact: Squirrel Installer, Portable Version, Squirrel nupkg, Squirrel RELEASES
|
||||
force_update: true
|
||||
on:
|
||||
APPVEYOR_REPO_TAG: true
|
||||
|
||||
environment:
|
||||
winget_token:
|
||||
secure: HKfVT2FYZITAG0qqMCePYhIem5a/gzvAgYDSlr6RlXfGmeBUOANUtgJ9X6fNroxN
|
||||
|
||||
on_success:
|
||||
- ps: |
|
||||
if ($env:APPVEYOR_REPO_BRANCH -eq "master" -and $env:APPVEYOR_REPO_TAG -eq "true")
|
||||
{
|
||||
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
|
||||
.\wingetcreate.exe update Flow-Launcher.Flow-Launcher -s true -u https://github.com/Flow-Launcher/Flow.Launcher/releases/download/v$env:flowVersion/Flow-Launcher-v$env:flowVersion.exe -v $env:flowVersion -t $env:winget_token
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue