mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-12 10:19:20 +08:00
Fixing stylecop violations (#5629)
This commit is contained in:
parent
0f90af3c7d
commit
ed36447bdf
@ -0,0 +1,17 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
public class ContextMenu
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Command { get; set; }
|
||||
|
||||
public string Argument { get; set; }
|
||||
|
||||
public string ImagePath { get; set; }
|
||||
}
|
||||
}
|
@ -1,114 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using Wox.Infrastructure.Logger;
|
||||
using Wox.Plugin;
|
||||
using Microsoft.Plugin.Indexer.SearchHelper;
|
||||
using System.Windows.Input;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Wox.Infrastructure;
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
internal class ContextMenuLoader : IContextMenu
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using Microsoft.Plugin.Indexer.SearchHelper;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Infrastructure.Logger;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
internal class ContextMenuLoader : IContextMenu
|
||||
{
|
||||
private readonly PluginInitContext _context;
|
||||
|
||||
public enum ResultType
|
||||
{
|
||||
Folder,
|
||||
File
|
||||
}
|
||||
|
||||
// Extensions for adding run as admin context menu item for applications
|
||||
private readonly string[] appExtensions = { ".exe", ".bat", ".appref-ms", ".lnk" };
|
||||
|
||||
public ContextMenuLoader(PluginInitContext context)
|
||||
{
|
||||
_context = context;
|
||||
File,
|
||||
}
|
||||
|
||||
// Extensions for adding run as admin context menu item for applications
|
||||
private readonly string[] appExtensions = { ".exe", ".bat", ".appref-ms", ".lnk" };
|
||||
|
||||
public ContextMenuLoader(PluginInitContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "We want to keep the process alive, and instead log and show an error message")]
|
||||
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
|
||||
{
|
||||
var contextMenus = new List<ContextMenuResult>();
|
||||
if (selectedResult.ContextData is SearchResult record)
|
||||
{
|
||||
ResultType type = Path.HasExtension(record.Path) ? ResultType.File : ResultType.Folder;
|
||||
|
||||
if (type == ResultType.File)
|
||||
{
|
||||
contextMenus.Add(CreateOpenContainingFolderResult(record));
|
||||
}
|
||||
|
||||
// Test to check if File can be Run as admin, if yes, we add a 'run as admin' context menu item
|
||||
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
|
||||
{
|
||||
var contextMenus = new List<ContextMenuResult>();
|
||||
if (selectedResult.ContextData is SearchResult record)
|
||||
{
|
||||
ResultType type = Path.HasExtension(record.Path) ? ResultType.File : ResultType.Folder;
|
||||
|
||||
if (type == ResultType.File)
|
||||
{
|
||||
contextMenus.Add(CreateOpenContainingFolderResult(record));
|
||||
}
|
||||
|
||||
// Test to check if File can be Run as admin, if yes, we add a 'run as admin' context menu item
|
||||
if (CanFileBeRunAsAdmin(record.Path))
|
||||
{
|
||||
contextMenus.Add(CreateRunAsAdminContextMenu(record));
|
||||
}
|
||||
|
||||
contextMenus.Add(new ContextMenuResult
|
||||
{
|
||||
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
|
||||
Title = _context.API.GetTranslation("Microsoft_plugin_indexer_copy_path"),
|
||||
Glyph = "\xE8C8",
|
||||
FontFamily = "Segoe MDL2 Assets",
|
||||
}
|
||||
|
||||
contextMenus.Add(new ContextMenuResult
|
||||
{
|
||||
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
|
||||
Title = _context.API.GetTranslation("Microsoft_plugin_indexer_copy_path"),
|
||||
Glyph = "\xE8C8",
|
||||
FontFamily = "Segoe MDL2 Assets",
|
||||
AcceleratorKey = Key.C,
|
||||
AcceleratorModifiers = ModifierKeys.Control,
|
||||
|
||||
Action = (context) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(record.Path);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var message = "Fail to set text in clipboard";
|
||||
LogException(message, e);
|
||||
_context.API.ShowMsg(message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
contextMenus.Add(new ContextMenuResult
|
||||
{
|
||||
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
|
||||
Title = _context.API.GetTranslation("Microsoft_plugin_indexer_open_in_console"),
|
||||
Glyph = "\xE756",
|
||||
FontFamily = "Segoe MDL2 Assets",
|
||||
AcceleratorModifiers = ModifierKeys.Control,
|
||||
|
||||
Action = (context) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(record.Path);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var message = "Fail to set text in clipboard";
|
||||
LogException(message, e);
|
||||
_context.API.ShowMsg(message);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
});
|
||||
contextMenus.Add(new ContextMenuResult
|
||||
{
|
||||
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
|
||||
Title = _context.API.GetTranslation("Microsoft_plugin_indexer_open_in_console"),
|
||||
Glyph = "\xE756",
|
||||
FontFamily = "Segoe MDL2 Assets",
|
||||
AcceleratorKey = Key.C,
|
||||
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
||||
|
||||
Action = (context) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (type == ResultType.File)
|
||||
{
|
||||
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
||||
|
||||
Action = (context) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (type == ResultType.File)
|
||||
{
|
||||
Helper.OpenInConsole(Path.GetDirectoryName(record.Path));
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
Helper.OpenInConsole(record.Path);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Exception($"|Microsoft.Plugin.Indexer.ContextMenuLoader.LoadContextMenus| Failed to open {record.Path} in console, {e.Message}", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return contextMenus;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Exception($"|Microsoft.Plugin.Indexer.ContextMenuLoader.LoadContextMenus| Failed to open {record.Path} in console, {e.Message}", e);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return contextMenus;
|
||||
}
|
||||
|
||||
// Function to add the context menu item to run as admin
|
||||
@ -122,7 +126,7 @@ namespace Microsoft.Plugin.Indexer
|
||||
Glyph = "\xE7EF",
|
||||
FontFamily = "Segoe MDL2 Assets",
|
||||
AcceleratorKey = Key.Enter,
|
||||
AcceleratorModifiers = (ModifierKeys.Control | ModifierKeys.Shift),
|
||||
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
||||
Action = _ =>
|
||||
{
|
||||
try
|
||||
@ -135,9 +139,8 @@ namespace Microsoft.Plugin.Indexer
|
||||
Log.Exception($"|Microsoft.Plugin.Indexer.ContextMenu| Failed to run {record.Path} as admin, {e.Message}", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Function to test if the file can be run as admin
|
||||
@ -151,43 +154,43 @@ namespace Microsoft.Plugin.Indexer
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "We want to keep the process alive, and instead log and show an error message")]
|
||||
private ContextMenuResult CreateOpenContainingFolderResult(SearchResult record)
|
||||
{
|
||||
return new ContextMenuResult
|
||||
{
|
||||
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
|
||||
Title = _context.API.GetTranslation("Microsoft_plugin_indexer_open_containing_folder"),
|
||||
Glyph = "\xE838",
|
||||
FontFamily = "Segoe MDL2 Assets",
|
||||
AcceleratorKey = Key.E,
|
||||
AcceleratorModifiers = (ModifierKeys.Control | ModifierKeys.Shift),
|
||||
Action = _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start("explorer.exe", $" /select,\"{record.Path}\"");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var message = $"Fail to open file at {record.Path}";
|
||||
LogException(message, e);
|
||||
_context.API.ShowMsg(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public static void LogException(string message, Exception e)
|
||||
{
|
||||
Log.Exception($"|Microsoft.Plugin.Folder.ContextMenu|{message}", e);
|
||||
}
|
||||
private ContextMenuResult CreateOpenContainingFolderResult(SearchResult record)
|
||||
{
|
||||
return new ContextMenuResult
|
||||
{
|
||||
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
|
||||
Title = _context.API.GetTranslation("Microsoft_plugin_indexer_open_containing_folder"),
|
||||
Glyph = "\xE838",
|
||||
FontFamily = "Segoe MDL2 Assets",
|
||||
AcceleratorKey = Key.E,
|
||||
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
||||
Action = _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start("explorer.exe", $" /select,\"{record.Path}\"");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var message = $"Fail to open file at {record.Path}";
|
||||
LogException(message, e);
|
||||
_context.API.ShowMsg(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public static void LogException(string message, Exception e)
|
||||
{
|
||||
Log.Exception($"|Microsoft.Plugin.Folder.ContextMenu|{message}", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
namespace Microsoft.Plugin.Indexer.DriveDetection
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.Plugin.Indexer.DriveDetection
|
||||
{
|
||||
public class IndexerDriveDetection
|
||||
{
|
||||
private bool IsEnhancedModeEnabled { get; set; } = false;
|
||||
private IRegistryWrapper _registryHelper;
|
||||
|
||||
private readonly IRegistryWrapper _registryHelper;
|
||||
|
||||
public bool IsDriveDetectionWarningCheckBoxSelected { get; set; } = false;
|
||||
|
||||
public IndexerDriveDetection(IRegistryWrapper registryHelper)
|
||||
@ -18,7 +24,7 @@
|
||||
return !(IsDriveDetectionWarningCheckBoxSelected || IsEnhancedModeEnabled);
|
||||
}
|
||||
|
||||
// To look up the registry entry for
|
||||
// To look up the registry entry for enhanced search
|
||||
private void GetEnhancedModeStatus()
|
||||
{
|
||||
string registryLocation = @"Software\Microsoft\Windows Search\Gather\Windows\SystemIndex";
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Input;
|
||||
using Microsoft.Plugin.Indexer;
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Microsoft.Plugin.Indexer.DriveDetection
|
||||
@ -16,13 +16,14 @@ namespace Microsoft.Plugin.Indexer.DriveDetection
|
||||
{
|
||||
if (regKey != null)
|
||||
{
|
||||
Object value = regKey.GetValue(valueName);
|
||||
object value = regKey.GetValue(valueName);
|
||||
if (value != null)
|
||||
{
|
||||
return (int)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,17 @@
|
||||
using System;
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
public class IndexerSettings
|
||||
{
|
||||
public List<ContextMenu> ContextMenus { get; } = new List<ContextMenu>();
|
||||
|
||||
public int MaxSearchCount { get; set; } = 100;
|
||||
|
||||
public bool UseLocationAsWorkingDir { get; set; } = false;
|
||||
}
|
||||
|
||||
public class ContextMenu
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Command { get; set; }
|
||||
public string Argument { get; set; }
|
||||
public string ImagePath { get; set; }
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
|
@ -1,5 +1,9 @@
|
||||
using Microsoft.Plugin.Indexer.SearchHelper;
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Plugin.Indexer.SearchHelper;
|
||||
|
||||
namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
|
@ -1,27 +1,27 @@
|
||||
using System;
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Wox.Plugin;
|
||||
using System.IO;
|
||||
using System.ComponentModel;
|
||||
using Wox.Infrastructure.Storage;
|
||||
using Microsoft.Plugin.Indexer.SearchHelper;
|
||||
using Microsoft.Search.Interop;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using System.Windows.Controls;
|
||||
using Wox.Infrastructure.Logger;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Plugin.Indexer.DriveDetection;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Controls;
|
||||
using Microsoft.Plugin.Indexer.DriveDetection;
|
||||
using Microsoft.Plugin.Indexer.SearchHelper;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using Wox.Infrastructure.Logger;
|
||||
using Wox.Infrastructure.Storage;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
internal class Main : ISettingProvider, IPlugin, ISavable, IPluginI18n, IContextMenu, IDisposable
|
||||
{
|
||||
|
||||
// This variable contains metadata about the Plugin
|
||||
private PluginInitContext _context;
|
||||
|
||||
@ -39,8 +39,10 @@ namespace Microsoft.Plugin.Indexer
|
||||
private readonly IndexerDriveDetection _driveDetection = new IndexerDriveDetection(new RegistryWrapper());
|
||||
|
||||
// Reserved keywords in oleDB
|
||||
private string ReservedStringPattern = @"^[\/\\\$\%]+$";
|
||||
private readonly string reservedStringPattern = @"^[\/\\\$\%]+$";
|
||||
|
||||
private string WarningIconPath { get; set; }
|
||||
|
||||
private IContextMenu _contextMenuLoader;
|
||||
private bool disposedValue;
|
||||
|
||||
@ -50,105 +52,108 @@ namespace Microsoft.Plugin.Indexer
|
||||
_storage.Save();
|
||||
}
|
||||
|
||||
|
||||
// This function uses the Windows indexer and returns the list of results obtained
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "We want to keep the process alive but will log the exception")]
|
||||
public List<Result> Query(Query query)
|
||||
{
|
||||
var results = new List<Result>();
|
||||
|
||||
if (!string.IsNullOrEmpty(query.Search))
|
||||
{
|
||||
var searchQuery = query.Search;
|
||||
if (_settings.MaxSearchCount <= 0)
|
||||
{
|
||||
_settings.MaxSearchCount = 50;
|
||||
}
|
||||
|
||||
var regexMatch = Regex.Match(searchQuery, ReservedStringPattern);
|
||||
|
||||
if (!regexMatch.Success)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(_driveDetection.DisplayWarning())
|
||||
{
|
||||
results.Add(new Result
|
||||
{
|
||||
Title = _context.API.GetTranslation("Microsoft_plugin_indexer_drivedetectionwarning"),
|
||||
SubTitle = _context.API.GetTranslation("Microsoft_plugin_indexer_disable_warning_in_settings"),
|
||||
IcoPath = WarningIconPath,
|
||||
Action = e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(GetWindowsSearchSettingsProcessInfo());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Exception("Microsoft.Plugin.Indexer", $"Unable to launch Windows Search Settings: {ex.Message}", ex, "Query");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var searchResultsList = _api.Search(searchQuery, maxCount: _settings.MaxSearchCount).ToList();
|
||||
foreach (var searchResult in searchResultsList)
|
||||
{
|
||||
var path = searchResult.Path;
|
||||
var toolTipTitle = string.Format(CultureInfo.CurrentCulture, "{0} : {1}", _context.API.GetTranslation("Microsoft_plugin_indexer_name"), searchResult.Title);
|
||||
var toolTipText = string.Format(CultureInfo.CurrentCulture, "{0} : {1}", _context.API.GetTranslation("Microsoft_plugin_indexer_path"), path);
|
||||
string workingDir = null;
|
||||
if (_settings.UseLocationAsWorkingDir)
|
||||
workingDir = Path.GetDirectoryName(path);
|
||||
|
||||
Result r = new Result();
|
||||
r.Title = searchResult.Title;
|
||||
r.SubTitle = "Search: " + path;
|
||||
r.IcoPath = path;
|
||||
r.ToolTipData = new ToolTipData(toolTipTitle, toolTipText);
|
||||
r.Action = c =>
|
||||
{
|
||||
bool hide;
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = path,
|
||||
UseShellExecute = true,
|
||||
WorkingDirectory = workingDir
|
||||
});
|
||||
hide = true;
|
||||
}
|
||||
catch (Win32Exception)
|
||||
{
|
||||
var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
|
||||
var msg = "Can't Open this file";
|
||||
_context.API.ShowMsg(name, msg, string.Empty);
|
||||
hide = false;
|
||||
}
|
||||
return hide;
|
||||
};
|
||||
r.ContextData = searchResult;
|
||||
|
||||
//If the result is a directory, then it's display should show a directory.
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
r.QueryTextDisplay = path;
|
||||
}
|
||||
|
||||
results.Add(r);
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
//The connection has closed, internal error of ExecuteReader()
|
||||
//Not showing this exception to the users
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Info(ex.ToString());
|
||||
if (!string.IsNullOrEmpty(query.Search))
|
||||
{
|
||||
var searchQuery = query.Search;
|
||||
if (_settings.MaxSearchCount <= 0)
|
||||
{
|
||||
_settings.MaxSearchCount = 50;
|
||||
}
|
||||
|
||||
var regexMatch = Regex.Match(searchQuery, reservedStringPattern);
|
||||
|
||||
if (!regexMatch.Success)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_driveDetection.DisplayWarning())
|
||||
{
|
||||
results.Add(new Result
|
||||
{
|
||||
Title = _context.API.GetTranslation("Microsoft_plugin_indexer_drivedetectionwarning"),
|
||||
SubTitle = _context.API.GetTranslation("Microsoft_plugin_indexer_disable_warning_in_settings"),
|
||||
IcoPath = WarningIconPath,
|
||||
Action = e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(GetWindowsSearchSettingsProcessInfo());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Exception("Microsoft.Plugin.Indexer", $"Unable to launch Windows Search Settings: {ex.Message}", ex, "Query");
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
var searchResultsList = _api.Search(searchQuery, maxCount: _settings.MaxSearchCount).ToList();
|
||||
foreach (var searchResult in searchResultsList)
|
||||
{
|
||||
var path = searchResult.Path;
|
||||
var toolTipTitle = string.Format(CultureInfo.CurrentCulture, "{0} : {1}", _context.API.GetTranslation("Microsoft_plugin_indexer_name"), searchResult.Title);
|
||||
var toolTipText = string.Format(CultureInfo.CurrentCulture, "{0} : {1}", _context.API.GetTranslation("Microsoft_plugin_indexer_path"), path);
|
||||
string workingDir = null;
|
||||
if (_settings.UseLocationAsWorkingDir)
|
||||
{
|
||||
workingDir = Path.GetDirectoryName(path);
|
||||
}
|
||||
|
||||
Result r = new Result();
|
||||
r.Title = searchResult.Title;
|
||||
r.SubTitle = "Search: " + path;
|
||||
r.IcoPath = path;
|
||||
r.ToolTipData = new ToolTipData(toolTipTitle, toolTipText);
|
||||
r.Action = c =>
|
||||
{
|
||||
bool hide;
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = path,
|
||||
UseShellExecute = true,
|
||||
WorkingDirectory = workingDir,
|
||||
});
|
||||
hide = true;
|
||||
}
|
||||
catch (Win32Exception)
|
||||
{
|
||||
var name = $"Plugin: {_context.CurrentPluginMetadata.Name}";
|
||||
var msg = "Can't Open this file";
|
||||
_context.API.ShowMsg(name, msg, string.Empty);
|
||||
hide = false;
|
||||
}
|
||||
|
||||
return hide;
|
||||
};
|
||||
r.ContextData = searchResult;
|
||||
|
||||
// If the result is a directory, then it's display should show a directory.
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
r.QueryTextDisplay = path;
|
||||
}
|
||||
|
||||
results.Add(r);
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// The connection has closed, internal error of ExecuteReader()
|
||||
// Not showing this exception to the users
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Info(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -180,7 +185,7 @@ namespace Microsoft.Plugin.Indexer
|
||||
}
|
||||
}
|
||||
|
||||
private void OnThemeChanged(Theme _, Theme newTheme)
|
||||
private void OnThemeChanged(Theme currentTheme, Theme newTheme)
|
||||
{
|
||||
UpdateIconPath(newTheme);
|
||||
}
|
||||
@ -203,11 +208,13 @@ namespace Microsoft.Plugin.Indexer
|
||||
{
|
||||
return _contextMenuLoader.LoadContextMenus(selectedResult);
|
||||
}
|
||||
|
||||
public void UpdateSettings(PowerLauncherSettings settings)
|
||||
{
|
||||
_settings.MaxSearchCount = settings.Properties.MaximumNumberOfResults;
|
||||
_driveDetection.IsDriveDetectionWarningCheckBoxSelected = settings.Properties.DisableDriveDetectionWarning;
|
||||
}
|
||||
|
||||
public Control CreateSettingPanel()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
@ -219,7 +226,7 @@ namespace Microsoft.Plugin.Indexer
|
||||
var ps = new ProcessStartInfo("ms-settings:cortana-windowssearch")
|
||||
{
|
||||
UseShellExecute = true,
|
||||
Verb = "open"
|
||||
Verb = "open",
|
||||
};
|
||||
|
||||
return ps;
|
||||
|
@ -1,119 +1,133 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<ProjectGuid>{F8B870EB-D5F5-45BA-9CF7-A5C459818820}</ProjectGuid>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.Plugin.Indexer</RootNamespace>
|
||||
<AssemblyName>Microsoft.Plugin.Indexer</AssemblyName>
|
||||
<useWPF>true</useWPF>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Microsoft.Plugin.Indexer\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutputPath>..\..\..\..\..\x64\Release\modules\launcher\Plugins\Microsoft.Plugin.Indexer\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<ProjectGuid>{F8B870EB-D5F5-45BA-9CF7-A5C459818820}</ProjectGuid>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.Plugin.Indexer</RootNamespace>
|
||||
<AssemblyName>Microsoft.Plugin.Indexer</AssemblyName>
|
||||
<useWPF>true</useWPF>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Microsoft.Plugin.Indexer\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutputPath>..\..\..\..\..\x64\Release\modules\launcher\Plugins\Microsoft.Plugin.Indexer\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Data.OleDb" Version="4.7.1" />
|
||||
<PackageReference Include="tlbimp-Microsoft.Search.Interop" Version="1.0.0">
|
||||
<NoWarn>NU1701</NoWarn>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\core\Microsoft.PowerToys.Settings.UI.Lib\Microsoft.PowerToys.Settings.UI.Lib.csproj" />
|
||||
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Images\indexer.dark.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\indexer.light.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Warning.dark.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Warning.light.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="plugin.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Languages\de.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\en.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\ja.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\pl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\tr.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\zh-cn.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\zh-tw.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>Wox.Test</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Data.OleDb" Version="4.7.1" />
|
||||
<PackageReference Include="tlbimp-Microsoft.Search.Interop" Version="1.0.0">
|
||||
<NoWarn>NU1701</NoWarn>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\core\Microsoft.PowerToys.Settings.UI.Lib\Microsoft.PowerToys.Settings.UI.Lib.csproj" />
|
||||
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Images\indexer.dark.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\indexer.light.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Warning.dark.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Images\Warning.light.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="plugin.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Languages\de.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\en.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\ja.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\pl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\tr.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\zh-cn.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Languages\zh-tw.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>Wox.Test</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\..\codeAnalysis\GlobalSuppressions.cs">
|
||||
<Link>GlobalSuppressions.cs</Link>
|
||||
</Compile>
|
||||
<AdditionalFiles Include="..\..\..\..\codeAnalysis\StyleCop.json">
|
||||
<Link>StyleCop.json</Link>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StyleCop.Analyzers">
|
||||
<Version>1.1.118</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Data.OleDb;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Plugin.Indexer.SearchHelper
|
||||
{
|
||||
|
@ -1,83 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.OleDb;
|
||||
|
||||
namespace Microsoft.Plugin.Indexer.SearchHelper
|
||||
{
|
||||
public class OleDBSearch : ISearch, IDisposable
|
||||
{
|
||||
private OleDbCommand command;
|
||||
private OleDbConnection conn;
|
||||
private OleDbDataReader WDSResults;
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.OleDb;
|
||||
|
||||
namespace Microsoft.Plugin.Indexer.SearchHelper
|
||||
{
|
||||
public class OleDBSearch : ISearch, IDisposable
|
||||
{
|
||||
private OleDbCommand command;
|
||||
private OleDbConnection conn;
|
||||
private OleDbDataReader wDSResults;
|
||||
private bool disposedValue;
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Security", "CA2100:Review SQL queries for security vulnerabilities",
|
||||
Justification = "sqlQuery does not come from user input but is generated via the ISearchQueryHelper::GenerateSqlFromUserQuery " +
|
||||
" see: https://docs.microsoft.com/en-us/windows/win32/search/-search-3x-wds-qryidx-searchqueryhelper#using-the-generatesqlfromuserquery-method")]
|
||||
public List<OleDBResult> Query(string connectionString, string sqlQuery)
|
||||
{
|
||||
List<OleDBResult> result = new List<OleDBResult>();
|
||||
|
||||
using (conn = new OleDbConnection(connectionString))
|
||||
{
|
||||
// open the connection
|
||||
conn.Open();
|
||||
|
||||
// now create an OleDB command object with the query we built above and the connection we just opened.
|
||||
using (command = new OleDbCommand(sqlQuery, conn))
|
||||
{
|
||||
using (WDSResults = command.ExecuteReader())
|
||||
{
|
||||
if (WDSResults.HasRows)
|
||||
{
|
||||
while (WDSResults.Read())
|
||||
{
|
||||
List<Object> fieldData = new List<object>();
|
||||
for (int i = 0; i < WDSResults.FieldCount; i++)
|
||||
{
|
||||
fieldData.Add(WDSResults.GetValue(i));
|
||||
}
|
||||
result.Add(new OleDBResult(fieldData));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Checks if all the variables related to database connection have been properly disposed
|
||||
public bool HaveAllDisposableItemsBeenDisposed()
|
||||
{
|
||||
bool commandDisposed = false;
|
||||
bool connDisposed = false;
|
||||
bool resultDisposed = false;
|
||||
|
||||
try
|
||||
{
|
||||
command.ExecuteReader();
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
commandDisposed = true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
WDSResults.Read();
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
resultDisposed = true;
|
||||
}
|
||||
|
||||
if (conn.State == System.Data.ConnectionState.Closed)
|
||||
{
|
||||
connDisposed = true;
|
||||
}
|
||||
|
||||
return commandDisposed && resultDisposed && connDisposed;
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage(
|
||||
"Security",
|
||||
"CA2100:Review SQL queries for security vulnerabilities",
|
||||
Justification = "sqlQuery does not come from user input but is generated via the ISearchQueryHelper::GenerateSqlFromUserQuery see: https://docs.microsoft.com/en-us/windows/win32/search/-search-3x-wds-qryidx-searchqueryhelper#using-the-generatesqlfromuserquery-method")]
|
||||
public List<OleDBResult> Query(string connectionString, string sqlQuery)
|
||||
{
|
||||
List<OleDBResult> result = new List<OleDBResult>();
|
||||
|
||||
using (conn = new OleDbConnection(connectionString))
|
||||
{
|
||||
// open the connection
|
||||
conn.Open();
|
||||
|
||||
// now create an OleDB command object with the query we built above and the connection we just opened.
|
||||
using (command = new OleDbCommand(sqlQuery, conn))
|
||||
{
|
||||
using (wDSResults = command.ExecuteReader())
|
||||
{
|
||||
if (wDSResults.HasRows)
|
||||
{
|
||||
while (wDSResults.Read())
|
||||
{
|
||||
List<object> fieldData = new List<object>();
|
||||
for (int i = 0; i < wDSResults.FieldCount; i++)
|
||||
{
|
||||
fieldData.Add(wDSResults.GetValue(i));
|
||||
}
|
||||
|
||||
result.Add(new OleDBResult(fieldData));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Checks if all the variables related to database connection have been properly disposed
|
||||
public bool HaveAllDisposableItemsBeenDisposed()
|
||||
{
|
||||
bool commandDisposed = false;
|
||||
bool connDisposed = false;
|
||||
bool resultDisposed = false;
|
||||
|
||||
try
|
||||
{
|
||||
command.ExecuteReader();
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
commandDisposed = true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
wDSResults.Read();
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
resultDisposed = true;
|
||||
}
|
||||
|
||||
if (conn.State == System.Data.ConnectionState.Closed)
|
||||
{
|
||||
connDisposed = true;
|
||||
}
|
||||
|
||||
return commandDisposed && resultDisposed && connDisposed;
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
@ -88,7 +94,7 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
|
||||
{
|
||||
command?.Dispose();
|
||||
conn?.Dispose();
|
||||
WDSResults?.Dispose();
|
||||
wDSResults?.Dispose();
|
||||
}
|
||||
|
||||
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
|
||||
@ -97,18 +103,11 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
|
||||
}
|
||||
}
|
||||
|
||||
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
|
||||
// ~OleDBSearch()
|
||||
// {
|
||||
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
// Dispose(disposing: false);
|
||||
// }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.Plugin.Indexer.SearchHelper
|
||||
{
|
||||
@ -13,6 +11,5 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
|
||||
|
||||
// Contains the Title of the file or folder
|
||||
public string Title { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,68 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Search.Interop;
|
||||
|
||||
namespace Microsoft.Plugin.Indexer.SearchHelper
|
||||
{
|
||||
public class WindowsSearchAPI
|
||||
{
|
||||
public bool DisplayHiddenFiles { get; set; }
|
||||
|
||||
private readonly ISearch WindowsIndexerSearch;
|
||||
private readonly object _lock = new object();
|
||||
private readonly UInt32 FILE_ATTRIBUTE_HIDDEN = 0x2;
|
||||
|
||||
public WindowsSearchAPI(ISearch windowsIndexerSearch, bool displayHiddenFiles = false)
|
||||
{
|
||||
this.WindowsIndexerSearch = windowsIndexerSearch;
|
||||
this.DisplayHiddenFiles = displayHiddenFiles;
|
||||
}
|
||||
|
||||
public List<SearchResult> ExecuteQuery(ISearchQueryHelper queryHelper, string keyword)
|
||||
{
|
||||
if(queryHelper == null)
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Search.Interop;
|
||||
|
||||
namespace Microsoft.Plugin.Indexer.SearchHelper
|
||||
{
|
||||
public class WindowsSearchAPI
|
||||
{
|
||||
public bool DisplayHiddenFiles { get; set; }
|
||||
|
||||
private readonly ISearch windowsIndexerSearch;
|
||||
private readonly object _lock = new object();
|
||||
private const uint _fileAttributeHidden = 0x2;
|
||||
|
||||
public WindowsSearchAPI(ISearch windowsIndexerSearch, bool displayHiddenFiles = false)
|
||||
{
|
||||
this.windowsIndexerSearch = windowsIndexerSearch;
|
||||
DisplayHiddenFiles = displayHiddenFiles;
|
||||
}
|
||||
|
||||
public List<SearchResult> ExecuteQuery(ISearchQueryHelper queryHelper, string keyword)
|
||||
{
|
||||
if (queryHelper == null)
|
||||
{
|
||||
throw new ArgumentNullException(paramName: nameof(queryHelper));
|
||||
}
|
||||
|
||||
List<SearchResult> _Result = new List<SearchResult>();
|
||||
|
||||
// Generate SQL from our parameters, converting the userQuery from AQS->WHERE clause
|
||||
string sqlQuery = queryHelper.GenerateSQLFromUserQuery(keyword);
|
||||
|
||||
// execute the command, which returns the results as an OleDBResults.
|
||||
List<OleDBResult> oleDBResults = WindowsIndexerSearch.Query(queryHelper.ConnectionString, sqlQuery);
|
||||
|
||||
// Loop over all records from the database
|
||||
foreach (OleDBResult oleDBResult in oleDBResults)
|
||||
{
|
||||
if (oleDBResult.FieldData[0] == DBNull.Value || oleDBResult.FieldData[1] == DBNull.Value || oleDBResult.FieldData[2] == DBNull.Value)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UInt32 fileAttributes = (UInt32)((Int64)oleDBResult.FieldData[2]);
|
||||
bool isFileHidden = (fileAttributes & FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN;
|
||||
|
||||
if (DisplayHiddenFiles || !isFileHidden)
|
||||
{
|
||||
var uri_path = new Uri((string)oleDBResult.FieldData[0]);
|
||||
var result = new SearchResult
|
||||
{
|
||||
Path = uri_path.LocalPath,
|
||||
Title = (string)oleDBResult.FieldData[1]
|
||||
};
|
||||
_Result.Add(result);
|
||||
}
|
||||
}
|
||||
|
||||
return _Result;
|
||||
}
|
||||
|
||||
|
||||
public static void ModifyQueryHelper(ref ISearchQueryHelper queryHelper, string pattern)
|
||||
{
|
||||
if(pattern == null)
|
||||
}
|
||||
|
||||
List<SearchResult> results = new List<SearchResult>();
|
||||
|
||||
// Generate SQL from our parameters, converting the userQuery from AQS->WHERE clause
|
||||
string sqlQuery = queryHelper.GenerateSQLFromUserQuery(keyword);
|
||||
|
||||
// execute the command, which returns the results as an OleDBResults.
|
||||
List<OleDBResult> oleDBResults = windowsIndexerSearch.Query(queryHelper.ConnectionString, sqlQuery);
|
||||
|
||||
// Loop over all records from the database
|
||||
foreach (OleDBResult oleDBResult in oleDBResults)
|
||||
{
|
||||
if (oleDBResult.FieldData[0] == DBNull.Value || oleDBResult.FieldData[1] == DBNull.Value || oleDBResult.FieldData[2] == DBNull.Value)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uint fileAttributes = (uint)((long)oleDBResult.FieldData[2]);
|
||||
bool isFileHidden = (fileAttributes & _fileAttributeHidden) == _fileAttributeHidden;
|
||||
|
||||
if (DisplayHiddenFiles || !isFileHidden)
|
||||
{
|
||||
var uri_path = new Uri((string)oleDBResult.FieldData[0]);
|
||||
var result = new SearchResult
|
||||
{
|
||||
Path = uri_path.LocalPath,
|
||||
Title = (string)oleDBResult.FieldData[1],
|
||||
};
|
||||
|
||||
results.Add(result);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static void ModifyQueryHelper(ref ISearchQueryHelper queryHelper, string pattern)
|
||||
{
|
||||
if (pattern == null)
|
||||
{
|
||||
throw new ArgumentNullException(paramName: nameof(pattern));
|
||||
}
|
||||
@ -70,62 +74,62 @@ namespace Microsoft.Plugin.Indexer.SearchHelper
|
||||
if (queryHelper == null)
|
||||
{
|
||||
throw new ArgumentNullException(paramName: nameof(queryHelper));
|
||||
}
|
||||
|
||||
// convert file pattern if it is not '*'. Don't create restriction for '*' as it includes all files.
|
||||
if (pattern != "*")
|
||||
{
|
||||
pattern = pattern.Replace("*", "%", StringComparison.InvariantCulture);
|
||||
pattern = pattern.Replace("?", "_", StringComparison.InvariantCulture);
|
||||
|
||||
if (pattern.Contains("%", StringComparison.InvariantCulture) || pattern.Contains("_", StringComparison.InvariantCulture))
|
||||
{
|
||||
queryHelper.QueryWhereRestrictions += " AND System.FileName LIKE '" + pattern + "' ";
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there are no wildcards we can use a contains which is much faster as it uses the index
|
||||
queryHelper.QueryWhereRestrictions += " AND Contains(System.FileName, '" + pattern + "') ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void InitQueryHelper(out ISearchQueryHelper queryHelper, int maxCount)
|
||||
{
|
||||
// This uses the Microsoft.Search.Interop assembly
|
||||
CSearchManager manager = new CSearchManager();
|
||||
|
||||
// SystemIndex catalog is the default catalog in Windows
|
||||
ISearchCatalogManager catalogManager = manager.GetCatalog("SystemIndex");
|
||||
|
||||
// Get the ISearchQueryHelper which will help us to translate AQS --> SQL necessary to query the indexer
|
||||
queryHelper = catalogManager.GetQueryHelper();
|
||||
|
||||
// Set the number of results we want. Don't set this property if all results are needed.
|
||||
queryHelper.QueryMaxResults = maxCount;
|
||||
|
||||
// Set list of columns we want to display, getting the path presently
|
||||
queryHelper.QuerySelectColumns = "System.ItemUrl, System.FileName, System.FileAttributes";
|
||||
|
||||
// Set additional query restriction
|
||||
queryHelper.QueryWhereRestrictions = "AND scope='file:'";
|
||||
|
||||
// To filter based on title for now
|
||||
queryHelper.QueryContentProperties = "System.FileName";
|
||||
|
||||
// Set sorting order
|
||||
queryHelper.QuerySorting = "System.DateModified DESC";
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResult> Search(string keyword, string pattern = "*", int maxCount = 30)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
ISearchQueryHelper queryHelper;
|
||||
InitQueryHelper(out queryHelper, maxCount);
|
||||
ModifyQueryHelper(ref queryHelper, pattern);
|
||||
return ExecuteQuery(queryHelper, keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert file pattern if it is not '*'. Don't create restriction for '*' as it includes all files.
|
||||
if (pattern != "*")
|
||||
{
|
||||
pattern = pattern.Replace("*", "%", StringComparison.InvariantCulture);
|
||||
pattern = pattern.Replace("?", "_", StringComparison.InvariantCulture);
|
||||
|
||||
if (pattern.Contains("%", StringComparison.InvariantCulture) || pattern.Contains("_", StringComparison.InvariantCulture))
|
||||
{
|
||||
queryHelper.QueryWhereRestrictions += " AND System.FileName LIKE '" + pattern + "' ";
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there are no wildcards we can use a contains which is much faster as it uses the index
|
||||
queryHelper.QueryWhereRestrictions += " AND Contains(System.FileName, '" + pattern + "') ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void InitQueryHelper(out ISearchQueryHelper queryHelper, int maxCount)
|
||||
{
|
||||
// This uses the Microsoft.Search.Interop assembly
|
||||
CSearchManager manager = new CSearchManager();
|
||||
|
||||
// SystemIndex catalog is the default catalog in Windows
|
||||
ISearchCatalogManager catalogManager = manager.GetCatalog("SystemIndex");
|
||||
|
||||
// Get the ISearchQueryHelper which will help us to translate AQS --> SQL necessary to query the indexer
|
||||
queryHelper = catalogManager.GetQueryHelper();
|
||||
|
||||
// Set the number of results we want. Don't set this property if all results are needed.
|
||||
queryHelper.QueryMaxResults = maxCount;
|
||||
|
||||
// Set list of columns we want to display, getting the path presently
|
||||
queryHelper.QuerySelectColumns = "System.ItemUrl, System.FileName, System.FileAttributes";
|
||||
|
||||
// Set additional query restriction
|
||||
queryHelper.QueryWhereRestrictions = "AND scope='file:'";
|
||||
|
||||
// To filter based on title for now
|
||||
queryHelper.QueryContentProperties = "System.FileName";
|
||||
|
||||
// Set sorting order
|
||||
queryHelper.QuerySorting = "System.DateModified DESC";
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResult> Search(string keyword, string pattern = "*", int maxCount = 30)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
ISearchQueryHelper queryHelper;
|
||||
InitQueryHelper(out queryHelper, maxCount);
|
||||
ModifyQueryHelper(ref queryHelper, pattern);
|
||||
return ExecuteQuery(queryHelper, keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user