Rename the [Ee]xts dir to ext (#38852)

**WARNING:** This PR will probably blow up all in-flight PRs

at some point in the early days of CmdPal, two of us created seperate
`Exts` and `exts` dirs. Depending on what the casing was on the branch
that you checked one of those out from, it'd get stuck like that on your
PC forever.

Windows didn't care, so we never noticed.

But GitHub does care, and now browsing the source on GitHub is basically
impossible.

Closes #38081
This commit is contained in:
Mike Griese
2025-04-15 06:07:22 -05:00
committed by GitHub
parent 60f50d853b
commit 2b5181b4c9
379 changed files with 35 additions and 35 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,93 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1825_18138)">
<path d="M8.3125 3L7.47871 1.89974C7.26684 1.62016 6.9931 1.39344 6.67896 1.23734C6.36481 1.08125 6.01879 1.00001 5.668 1H1C0.734784 1 0.48043 1.10536 0.292893 1.29289C0.105357 1.48043 0 1.73478 0 2L0 12C0.00155124 12.53 0.212763 13.0378 0.5875 13.4125C0.962237 13.7872 1.47004 13.9984 2 14H14C14.53 13.9984 15.0378 13.7872 15.4125 13.4125C15.7872 13.0378 15.9984 12.53 16 12V4C16 3.73478 15.8946 3.48043 15.7071 3.29289C15.5196 3.10536 15.2652 3 15 3H8.3125Z" fill="url(#paint0_linear_1825_18138)"/>
<mask id="mask0_1825_18138" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="1" width="16" height="13">
<path d="M8.3125 3L7.47871 1.89974C7.26684 1.62016 6.9931 1.39344 6.67896 1.23734C6.36481 1.08125 6.01879 1.00001 5.668 1H1C0.734784 1 0.48043 1.10536 0.292893 1.29289C0.105357 1.48043 0 1.73478 0 2L0 12C0.00155124 12.53 0.212763 13.0378 0.5875 13.4125C0.962237 13.7872 1.47004 13.9984 2 14H14C14.53 13.9984 15.0378 13.7872 15.4125 13.4125C15.7872 13.0378 15.9984 12.53 16 12V4C16 3.73478 15.8946 3.48043 15.7071 3.29289C15.5196 3.10536 15.2652 3 15 3H8.3125Z" fill="url(#paint1_linear_1825_18138)"/>
</mask>
<g mask="url(#mask0_1825_18138)">
<g filter="url(#filter0_dd_1825_18138)">
<path d="M14.9985 5.00187H10L8 5.00172C7.62917 5.19449 6.41839 4.9973 6.00047 5.00171H1.00151C0.868112 4.99367 0.734525 5.01401 0.609573 5.06142C0.484622 5.10882 0.37115 5.18219 0.276655 5.27669C0.18216 5.37119 0.108792 5.48467 0.061398 5.60962C0.0140044 5.73458 -0.00633622 5.86817 0.00172002 6.00156V13.9986C-0.00634109 14.132 0.0139961 14.2656 0.0613881 14.3905C0.10878 14.5155 0.182148 14.6289 0.276644 14.7234C0.37114 14.8179 0.484614 14.8913 0.609568 14.9387C0.734521 14.9861 0.868111 15.0065 1.00151 14.9984H14.9985C15.1319 15.0065 15.2655 14.9861 15.3904 14.9387C15.5154 14.8913 15.6289 14.8179 15.7234 14.7234C15.8178 14.6289 15.8912 14.5155 15.9386 14.3905C15.986 14.2655 16.0064 14.132 15.9983 13.9986V6.00171C16.0064 5.86832 15.986 5.73473 15.9386 5.60977C15.8912 5.48481 15.8179 5.37134 15.7234 5.27683C15.6289 5.18233 15.5154 5.10896 15.3905 5.06156C15.2655 5.01416 15.1319 4.99382 14.9985 5.00187Z" fill="url(#paint2_linear_1825_18138)"/>
</g>
</g>
<path d="M14.9985 4.00172H8.2L7.20022 4.70161C6.82939 4.89438 6.41839 4.99714 6.00047 5.00156H1.00151C0.868112 4.99351 0.734525 5.01386 0.609573 5.06126C0.484622 5.10866 0.37115 5.18203 0.276655 5.27654C0.18216 5.37104 0.108792 5.48451 0.061398 5.60947C0.0140044 5.73442 -0.00633622 5.86801 0.00172002 6.00141V13.9984C-0.00634109 14.1318 0.0139961 14.2654 0.0613881 14.3904C0.10878 14.5153 0.182148 14.6288 0.276644 14.7233C0.37114 14.8178 0.484614 14.8912 0.609568 14.9386C0.734521 14.986 0.868111 15.0063 1.00151 14.9983H14.9985C15.1319 15.0063 15.2655 14.9859 15.3904 14.9385C15.5154 14.8911 15.6289 14.8178 15.7234 14.7233C15.8178 14.6288 15.8912 14.5153 15.9386 14.3903C15.986 14.2654 16.0064 14.1318 15.9983 13.9984V5.00156C16.0064 4.86816 15.986 4.73457 15.9386 4.60961C15.8912 4.48466 15.8179 4.37118 15.7234 4.27668C15.6289 4.18218 15.5154 4.1088 15.3905 4.0614C15.2655 4.01401 15.1319 3.99366 14.9985 4.00172H14.9985Z" fill="url(#paint3_linear_1825_18138)"/>
<path opacity="0.25" d="M15.7017 4.30036C15.6137 4.20263 15.5056 4.1252 15.3847 4.0734C15.2638 4.0216 15.1332 3.99668 15.0017 4.00036H8.20172L7.20172 4.70036C6.83081 4.89316 6.41972 4.99594 6.00172 5.00036H1.00172C0.868297 4.9923 0.734682 5.01264 0.609705 5.06005C0.484727 5.10745 0.371231 5.18083 0.276715 5.27535C0.182198 5.36987 0.108814 5.48336 0.0614098 5.60834C0.0140056 5.73332 -0.00633928 5.86693 0.00171929 6.00036V7.00036C-0.00634091 6.86693 0.0140029 6.73332 0.0614065 6.60834C0.10881 6.48336 0.182194 6.36986 0.276711 6.27535C0.371227 6.18083 0.484724 6.10745 0.609703 6.06004C0.734681 6.01264 0.868296 5.9923 1.00172 6.00036H6.00172C6.60283 5.98827 7.18978 5.81563 7.70172 5.50036L8.50172 5.00036H15.0017C15.1351 4.9923 15.2688 5.01265 15.3937 5.06006C15.5187 5.10746 15.6322 5.18085 15.7267 5.27536C15.8212 5.36988 15.8946 5.48337 15.942 5.60835C15.9894 5.73332 16.0098 5.86693 16.0017 6.00036V5.00036C16.0054 4.86891 15.9805 4.73823 15.9287 4.61736C15.8769 4.49649 15.7995 4.38833 15.7017 4.30036Z" fill="url(#paint4_linear_1825_18138)"/>
<mask id="mask1_1825_18138" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="4" width="16" height="11">
<path d="M14.9985 4.00172H8.2L7.20022 4.70161C6.82939 4.89438 6.41839 4.99714 6.00047 5.00156H1.00151C0.868112 4.99351 0.734525 5.01386 0.609573 5.06126C0.484622 5.10866 0.37115 5.18203 0.276655 5.27654C0.18216 5.37104 0.108792 5.48451 0.061398 5.60947C0.0140044 5.73442 -0.00633622 5.86801 0.00172002 6.00141V13.9984C-0.00634109 14.1318 0.0139961 14.2654 0.0613881 14.3904C0.10878 14.5153 0.182148 14.6288 0.276644 14.7233C0.37114 14.8178 0.484614 14.8912 0.609568 14.9386C0.734521 14.986 0.868111 15.0063 1.00151 14.9983H14.9985C15.1319 15.0063 15.2655 14.9859 15.3904 14.9385C15.5154 14.8911 15.6289 14.8178 15.7234 14.7233C15.8178 14.6288 15.8912 14.5153 15.9386 14.3903C15.986 14.2654 16.0064 14.1318 15.9983 13.9984V5.00156C16.0064 4.86816 15.986 4.73457 15.9386 4.60961C15.8912 4.48466 15.8179 4.37118 15.7234 4.27668C15.6289 4.18218 15.5154 4.1088 15.3905 4.0614C15.2655 4.01401 15.1319 3.99366 14.9985 4.00172H14.9985Z" fill="url(#paint5_linear_1825_18138)"/>
</mask>
<g mask="url(#mask1_1825_18138)">
<g filter="url(#filter1_dd_1825_18138)">
<path d="M5 10H11C11.5304 10 12.0391 10.2107 12.4142 10.5858C12.7893 10.9609 13 11.4696 13 12V15H3V12C3 11.4696 3.21071 10.9609 3.58579 10.5858C3.96086 10.2107 4.46957 10 5 10Z" fill="url(#paint6_linear_1825_18138)"/>
</g>
</g>
<path d="M5 10H11C11.5304 10 12.0391 10.2107 12.4142 10.5858C12.7893 10.9609 13 11.4696 13 12V15H3V12C3 11.4696 3.21071 10.9609 3.58579 10.5858C3.96086 10.2107 4.46957 10 5 10Z" fill="url(#paint7_linear_1825_18138)"/>
<path d="M10.5 12H5.5C5.22386 12 5 12.2239 5 12.5C5 12.7761 5.22386 13 5.5 13H10.5C10.7761 13 11 12.7761 11 12.5C11 12.2239 10.7761 12 10.5 12Z" fill="#114A8B"/>
</g>
<defs>
<filter id="filter0_dd_1825_18138" x="-1" y="4" width="18" height="12" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="0.166667"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1825_18138"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="0.5"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_1825_18138" result="effect2_dropShadow_1825_18138"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_1825_18138" result="shape"/>
</filter>
<filter id="filter1_dd_1825_18138" x="2" y="9" width="12" height="7" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="0.166667"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1825_18138"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="0.5"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_1825_18138" result="effect2_dropShadow_1825_18138"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_1825_18138" result="shape"/>
</filter>
<linearGradient id="paint0_linear_1825_18138" x1="11.4683" y1="14.139" x2="4.1515" y2="1.4659" gradientUnits="userSpaceOnUse">
<stop offset="0.1135" stop-color="#D18B00"/>
<stop offset="0.6162" stop-color="#E09F00"/>
</linearGradient>
<linearGradient id="paint1_linear_1825_18138" x1="11.4683" y1="14.139" x2="4.1515" y2="1.4659" gradientUnits="userSpaceOnUse">
<stop offset="0.1135" stop-color="#D18B00"/>
<stop offset="0.6162" stop-color="#E09F00"/>
</linearGradient>
<linearGradient id="paint2_linear_1825_18138" x1="12.1767" y1="16.7345" x2="4.48067" y2="3.40451" gradientUnits="userSpaceOnUse">
<stop stop-color="#F5B300"/>
<stop offset="0.5" stop-color="#FFCB3C"/>
<stop offset="1" stop-color="#FFD762"/>
</linearGradient>
<linearGradient id="paint3_linear_1825_18138" x1="12.1767" y1="16.7343" x2="4.48067" y2="3.40435" gradientUnits="userSpaceOnUse">
<stop stop-color="#F5B300"/>
<stop offset="0.5" stop-color="#FFCB3C"/>
<stop offset="1" stop-color="#FFD762"/>
</linearGradient>
<linearGradient id="paint4_linear_1825_18138" x1="0.430309" y1="5.50017" x2="16.0017" y2="5.50017" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint5_linear_1825_18138" x1="12.1767" y1="16.7343" x2="4.48067" y2="3.40435" gradientUnits="userSpaceOnUse">
<stop stop-color="#F5B300"/>
<stop offset="0.5" stop-color="#FFCB3C"/>
<stop offset="1" stop-color="#FFD762"/>
</linearGradient>
<linearGradient id="paint6_linear_1825_18138" x1="8.30516" y1="15.1422" x2="7.36003" y2="9.7821" gradientUnits="userSpaceOnUse">
<stop stop-color="#0062B4"/>
<stop offset="1" stop-color="#1493DF"/>
</linearGradient>
<linearGradient id="paint7_linear_1825_18138" x1="8.30516" y1="15.1422" x2="7.36003" y2="9.7821" gradientUnits="userSpaceOnUse">
<stop stop-color="#0062B4"/>
<stop offset="1" stop-color="#1493DF"/>
</linearGradient>
<clipPath id="clip0_1825_18138">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@@ -0,0 +1,34 @@
// 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 Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Indexer.Commands;
internal sealed partial class CopyPathCommand : InvokableCommand
{
private readonly IndexerItem _item;
internal CopyPathCommand(IndexerItem item)
{
this._item = item;
this.Name = Resources.Indexer_Command_CopyPath;
this.Icon = new IconInfo("\uE8c8");
}
public override CommandResult Invoke()
{
try
{
ClipboardHelper.SetText(_item.FullPath);
}
catch
{
}
return CommandResult.KeepOpen();
}
}

View File

@@ -0,0 +1,44 @@
// 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.ComponentModel;
using System.Diagnostics;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Indexer.Commands;
internal sealed partial class OpenFileCommand : InvokableCommand
{
private readonly IndexerItem _item;
internal OpenFileCommand(IndexerItem item)
{
this._item = item;
this.Name = Resources.Indexer_Command_OpenFile;
this.Icon = Icons.OpenFile;
}
public override CommandResult Invoke()
{
using (var process = new Process())
{
process.StartInfo.FileName = _item.FullPath;
process.StartInfo.UseShellExecute = true;
try
{
process.Start();
}
catch (Win32Exception ex)
{
Logger.LogError($"Unable to open {_item.FullPath}", ex);
}
}
return CommandResult.GoHome();
}
}

View File

@@ -0,0 +1,45 @@
// 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.ComponentModel;
using System.Diagnostics;
using System.IO;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Indexer.Commands;
internal sealed partial class OpenInConsoleCommand : InvokableCommand
{
private readonly IndexerItem _item;
internal OpenInConsoleCommand(IndexerItem item)
{
this._item = item;
this.Name = Resources.Indexer_Command_OpenPathInConsole;
this.Icon = new IconInfo("\uE756");
}
public override CommandResult Invoke()
{
using (var process = new Process())
{
process.StartInfo.WorkingDirectory = Path.GetDirectoryName(_item.FullPath);
process.StartInfo.FileName = "cmd.exe";
try
{
process.Start();
}
catch (Win32Exception ex)
{
Logger.LogError($"Unable to open {_item.FullPath}", ex);
}
}
return CommandResult.GoHome();
}
}

View File

@@ -0,0 +1,71 @@
// 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.Runtime.InteropServices;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Native;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.Shell;
using Windows.Win32.UI.WindowsAndMessaging;
namespace Microsoft.CmdPal.Ext.Indexer.Commands;
internal sealed partial class OpenPropertiesCommand : InvokableCommand
{
private readonly IndexerItem _item;
private static unsafe bool ShowFileProperties(string filename)
{
var propertiesPtr = Marshal.StringToHGlobalUni("properties");
var filenamePtr = Marshal.StringToHGlobalUni(filename);
try
{
var filenamePCWSTR = new PCWSTR((char*)filenamePtr);
var propertiesPCWSTR = new PCWSTR((char*)propertiesPtr);
var info = new SHELLEXECUTEINFOW
{
cbSize = (uint)Marshal.SizeOf<SHELLEXECUTEINFOW>(),
lpVerb = propertiesPCWSTR,
lpFile = filenamePCWSTR,
nShow = (int)SHOW_WINDOW_CMD.SW_SHOW,
fMask = NativeHelpers.SEEMASKINVOKEIDLIST,
};
return PInvoke.ShellExecuteEx(ref info);
}
finally
{
Marshal.FreeHGlobal(filenamePtr);
Marshal.FreeHGlobal(propertiesPtr);
}
}
internal OpenPropertiesCommand(IndexerItem item)
{
this._item = item;
this.Name = Resources.Indexer_Command_OpenProperties;
this.Icon = new IconInfo("\uE90F");
}
public override CommandResult Invoke()
{
try
{
ShowFileProperties(_item.FullPath);
}
catch (Exception ex)
{
Logger.LogError("Error showing file properties: ", ex);
}
return CommandResult.GoHome();
}
}

View File

@@ -0,0 +1,62 @@
// 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.Runtime.InteropServices;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Native;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.Shell;
using Windows.Win32.UI.WindowsAndMessaging;
namespace Microsoft.CmdPal.Ext.Indexer.Commands;
internal sealed partial class OpenWithCommand : InvokableCommand
{
private readonly IndexerItem _item;
private static unsafe bool OpenWith(string filename)
{
var filenamePtr = Marshal.StringToHGlobalUni(filename);
var verbPtr = Marshal.StringToHGlobalUni("openas");
try
{
var filenamePCWSTR = new PCWSTR((char*)filenamePtr);
var verbPCWSTR = new PCWSTR((char*)verbPtr);
var info = new SHELLEXECUTEINFOW
{
cbSize = (uint)Marshal.SizeOf<SHELLEXECUTEINFOW>(),
lpVerb = verbPCWSTR,
lpFile = filenamePCWSTR,
nShow = (int)SHOW_WINDOW_CMD.SW_SHOWNORMAL,
fMask = NativeHelpers.SEEMASKINVOKEIDLIST,
};
return PInvoke.ShellExecuteEx(ref info);
}
finally
{
Marshal.FreeHGlobal(filenamePtr);
Marshal.FreeHGlobal(verbPtr);
}
}
internal OpenWithCommand(IndexerItem item)
{
this._item = item;
this.Name = Resources.Indexer_Command_OpenWith;
this.Icon = new IconInfo("\uE7AC");
}
public override CommandResult Invoke()
{
OpenWith(_item.FullPath);
return CommandResult.GoHome();
}
}

View File

@@ -0,0 +1,27 @@
// 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.IO;
namespace Microsoft.CmdPal.Ext.Indexer.Data;
internal sealed class IndexerItem
{
internal string FullPath { get; init; }
internal string FileName { get; init; }
internal bool IsDirectory()
{
if (!Path.Exists(FullPath))
{
return false;
}
var attr = File.GetAttributes(FullPath);
// detect whether it is a directory or file
return (attr & FileAttributes.Directory) == FileAttributes.Directory;
}
}

View File

@@ -0,0 +1,57 @@
// 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.CmdPal.Ext.Indexer.Commands;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Indexer.Data;
internal sealed partial class IndexerListItem : ListItem
{
internal string FilePath { get; private set; }
public IndexerListItem(
IndexerItem indexerItem,
IncludeBrowseCommand browseByDefault = IncludeBrowseCommand.Include)
: base(new OpenFileCommand(indexerItem))
{
FilePath = indexerItem.FullPath;
Title = indexerItem.FileName;
Subtitle = indexerItem.FullPath;
List<CommandContextItem> context = [];
if (indexerItem.IsDirectory())
{
var directoryPage = new DirectoryPage(indexerItem.FullPath);
if (browseByDefault == IncludeBrowseCommand.AsDefault)
{
// Swap the open file command into the context menu
context.Add(new CommandContextItem(Command));
Command = directoryPage;
}
else if (browseByDefault == IncludeBrowseCommand.Include)
{
context.Add(new CommandContextItem(directoryPage));
}
}
MoreCommands = [
..context,
new CommandContextItem(new OpenWithCommand(indexerItem)),
new CommandContextItem(new ShowFileInFolderCommand(indexerItem.FullPath) { Name = Resources.Indexer_Command_ShowInFolder }),
new CommandContextItem(new CopyPathCommand(indexerItem)),
new CommandContextItem(new OpenInConsoleCommand(indexerItem)),
new CommandContextItem(new OpenPropertiesCommand(indexerItem)),
];
}
}
internal enum IncludeBrowseCommand
{
AsDefault = 0,
Include = 1,
Exclude = 2,
}

View File

@@ -0,0 +1,54 @@
// 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.IO;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Storage.Streams;
namespace Microsoft.CmdPal.Ext.Indexer;
internal sealed partial class FallbackOpenFileItem : FallbackCommandItem
{
public FallbackOpenFileItem()
: base(new NoOpCommand(), Resources.Indexer_Find_Path_fallback_display_title)
{
Title = string.Empty;
Subtitle = string.Empty;
}
public override void UpdateQuery(string query)
{
if (Path.Exists(query))
{
var item = new IndexerItem() { FullPath = query, FileName = Path.GetFileName(query) };
var listItemForUs = new IndexerListItem(item, IncludeBrowseCommand.AsDefault);
Command = listItemForUs.Command;
MoreCommands = listItemForUs.MoreCommands;
Subtitle = item.FileName;
Title = item.FullPath;
Icon = listItemForUs.Icon;
try
{
var stream = ThumbnailHelper.GetThumbnail(item.FullPath).Result;
if (stream != null)
{
var data = new IconData(RandomAccessStreamReference.CreateFromStream(stream));
Icon = new IconInfo(data, data);
}
}
catch
{
}
}
else
{
Title = string.Empty;
Subtitle = string.Empty;
Command = new NoOpCommand();
}
}
}

View File

@@ -0,0 +1,49 @@
// 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 ManagedCommon;
using Windows.Win32;
using Windows.Win32.System.Com;
using Windows.Win32.System.Search;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer;
internal static class DataSourceManager
{
private static readonly Guid CLSIDCollatorDataSource = new("9E175B8B-F52A-11D8-B9A5-505054503030");
private static IDBInitialize _dataSource;
public static IDBInitialize GetDataSource()
{
if (_dataSource == null)
{
InitializeDataSource();
}
return _dataSource;
}
private static bool InitializeDataSource()
{
var hr = PInvoke.CoCreateInstance(CLSIDCollatorDataSource, null, CLSCTX.CLSCTX_INPROC_SERVER, typeof(IDBInitialize).GUID, out var dataSourceObj);
if (hr != 0)
{
Logger.LogError("CoCreateInstance failed: " + hr);
return false;
}
if (dataSourceObj == null)
{
Logger.LogError("CoCreateInstance failed: dataSourceObj is null");
return false;
}
_dataSource = (IDBInitialize)dataSourceObj;
_dataSource.Initialize();
return true;
}
}

View File

@@ -0,0 +1,21 @@
// 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.Runtime.InteropServices;
using Windows.Win32.Storage.IndexServer;
using Windows.Win32.System.Com.StructuredStorage;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.OleDB;
[StructLayout(LayoutKind.Sequential)]
internal struct DBPROP
{
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
public uint dwPropertyID;
public uint dwOptions;
public uint dwStatus;
public DBID colid;
public PROPVARIANT vValue;
#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
}

View File

@@ -0,0 +1,18 @@
// 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.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.OleDB;
[StructLayout(LayoutKind.Sequential)]
public struct DBPROPIDSET
{
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
public IntPtr rgPropertyIDs; // Pointer to array of property IDs
public uint cPropertyIDs; // Number of properties in array
public Guid guidPropertySet; // GUID of the property set
#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
}

View File

@@ -0,0 +1,18 @@
// 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.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.OleDB;
[StructLayout(LayoutKind.Sequential)]
public struct DBPROPSET
{
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
public IntPtr rgProperties; // Pointer to an array of DBPROP
public uint cProperties; // Number of properties in the array
public Guid guidPropertySet; // GUID of the property set
#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
}

View File

@@ -0,0 +1,43 @@
// 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.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.OleDB;
[ComImport]
[Guid("0c733a7c-2a1c-11ce-ade5-00aa0044773d")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRowset
{
[PreserveSig]
int AddRefRows(
uint cRows,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] rghRows,
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] rgRefCounts,
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] rgRowStatus);
[PreserveSig]
int GetData(
IntPtr hRow,
IntPtr hAccessor,
IntPtr pData);
[PreserveSig]
int GetNextRows(
IntPtr hReserved,
long lRowsOffset,
long cRows,
out uint pcRowsObtained,
out IntPtr prghRows);
[PreserveSig]
int ReleaseRows(
uint cRows,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] rghRows,
IntPtr rgRowOptions,
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] rgRefCounts,
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] rgRowStatus);
}

View File

@@ -0,0 +1,32 @@
// 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.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.OleDB;
[ComImport]
[Guid("0C733A55-2A1C-11CE-ADE5-00AA0044773D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRowsetInfo
{
[PreserveSig]
int GetProperties(
uint cPropertyIDSets,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] DBPROPIDSET[] rgPropertyIDSets,
out ulong pcPropertySets,
out IntPtr prgPropertySets);
[PreserveSig]
int GetReferencedRowset(
uint iOrdinal,
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppReferencedRowset);
[PreserveSig]
int GetSpecification(
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppSpecification);
}

View File

@@ -0,0 +1,479 @@
// 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.Concurrent;
using System.Runtime.InteropServices;
using System.Threading;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Indexer.OleDB;
using Microsoft.CmdPal.Ext.Indexer.Indexer.Utils;
using Microsoft.CmdPal.Ext.Indexer.Native;
using Windows.Win32;
using Windows.Win32.System.Com;
using Windows.Win32.System.Search;
using Windows.Win32.UI.Shell.PropertiesSystem;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer;
internal sealed partial class SearchQuery : IDisposable
{
private readonly Lock _lockObject = new(); // Lock object for synchronization
private readonly DBPROPIDSET dbPropIdSet;
private uint reuseWhereID;
private EventWaitHandle queryCompletedEvent;
private Timer queryTpTimer;
private IRowset currentRowset;
private IRowset reuseRowset;
public uint Cookie { get; set; }
public string SearchText { get; private set; }
public ConcurrentQueue<SearchResult> SearchResults { get; private set; } = [];
public SearchQuery()
{
dbPropIdSet = new DBPROPIDSET
{
rgPropertyIDs = Marshal.AllocCoTaskMem(sizeof(uint)), // Allocate memory for the property ID array
cPropertyIDs = 1,
guidPropertySet = new Guid("AA6EE6B0-E828-11D0-B23E-00AA0047FC01"), // DBPROPSET_MSIDXS_ROWSETEXT,
};
// Copy the property ID into the allocated memory
Marshal.WriteInt32(dbPropIdSet.rgPropertyIDs, 8); // MSIDXSPROP_WHEREID
Init();
}
private void Init()
{
// Create all the objects we will want cached
try
{
queryTpTimer = new Timer(QueryTimerCallback, this, Timeout.Infinite, Timeout.Infinite);
if (queryTpTimer == null)
{
Logger.LogError("Failed to create query timer");
return;
}
queryCompletedEvent = new EventWaitHandle(false, EventResetMode.ManualReset);
if (queryCompletedEvent == null)
{
Logger.LogError("Failed to create query completed event");
return;
}
// Execute a synchronous query on file items to prime the index and keep that handle around
PrimeIndexAndCacheWhereId();
}
catch (Exception ex)
{
Logger.LogError("Exception at SearchUXQueryHelper Init", ex);
}
}
public void WaitForQueryCompletedEvent() => queryCompletedEvent.WaitOne();
public void CancelOutstandingQueries()
{
Logger.LogDebug("Cancel query " + SearchText);
// Are we currently doing work? If so, let's cancel
lock (_lockObject)
{
if (queryTpTimer != null)
{
queryTpTimer.Change(Timeout.Infinite, Timeout.Infinite);
queryTpTimer.Dispose();
queryTpTimer = null;
}
Init();
}
}
public void Execute(string searchText, uint cookie)
{
SearchText = searchText;
Cookie = cookie;
ExecuteSyncInternal();
}
public static void QueryTimerCallback(object state)
{
var pQueryHelper = (SearchQuery)state;
pQueryHelper.ExecuteSyncInternal();
}
private void ExecuteSyncInternal()
{
lock (_lockObject)
{
var queryStr = QueryStringBuilder.GenerateQuery(SearchText, reuseWhereID);
try
{
// We need to generate a search query string with the search text the user entered above
if (currentRowset != null)
{
if (reuseRowset != null)
{
Marshal.ReleaseComObject(reuseRowset);
}
// We have a previous rowset, this means the user is typing and we should store this
// recapture the where ID from this so the next ExecuteSync call will be faster
reuseRowset = currentRowset;
reuseWhereID = GetReuseWhereId(reuseRowset);
}
currentRowset = ExecuteCommand(queryStr);
SearchResults.Clear();
}
catch (Exception ex)
{
Logger.LogError("Error executing query", ex);
}
finally
{
queryCompletedEvent.Set();
}
}
}
private bool HandleRow(IGetRow getRow, nuint rowHandle)
{
object propertyStorePtr = null;
try
{
getRow.GetRowFromHROW(null, rowHandle, typeof(IPropertyStore).GUID, out propertyStorePtr);
var propertyStore = (IPropertyStore)propertyStorePtr;
if (propertyStore == null)
{
Logger.LogError("Failed to get IPropertyStore interface");
return false;
}
var searchResult = SearchResult.Create(propertyStore);
if (searchResult == null)
{
Logger.LogError("Failed to create search result");
return false;
}
SearchResults.Enqueue(searchResult);
return true;
}
catch (Exception ex)
{
Logger.LogError("Error handling row", ex);
return false;
}
finally
{
// Ensure the COM object is released if not returned
if (propertyStorePtr != null)
{
Marshal.ReleaseComObject(propertyStorePtr);
}
}
}
public bool FetchRows(int offset, int limit)
{
if (currentRowset == null)
{
Logger.LogError("No rowset to fetch rows from");
return false;
}
if (currentRowset is not IGetRow)
{
Logger.LogInfo("Reset the current rowset");
ExecuteSyncInternal();
}
if (currentRowset is not IGetRow getRow)
{
Logger.LogError("Rowset does not support IGetRow interface");
return false;
}
uint rowCountReturned;
var prghRows = IntPtr.Zero;
try
{
var res = currentRowset.GetNextRows(IntPtr.Zero, offset, limit, out rowCountReturned, out prghRows);
if (res < 0)
{
Logger.LogError($"Error fetching rows: {res}");
return false;
}
if (rowCountReturned == 0)
{
// No more rows to fetch
return false;
}
// Marshal the row handles
var rowHandles = new IntPtr[rowCountReturned];
Marshal.Copy(prghRows, rowHandles, 0, (int)rowCountReturned);
for (var i = 0; i < rowCountReturned; i++)
{
var rowHandle = Marshal.ReadIntPtr(prghRows, i * IntPtr.Size);
if (!HandleRow(getRow, (nuint)rowHandle))
{
break;
}
}
res = currentRowset.ReleaseRows(rowCountReturned, rowHandles, IntPtr.Zero, null, null);
if (res != 0)
{
Logger.LogError($"Error releasing rows: {res}");
}
Marshal.FreeCoTaskMem(prghRows);
prghRows = IntPtr.Zero;
return true;
}
catch (Exception ex)
{
Logger.LogError("Error fetching rows", ex);
return false;
}
finally
{
if (prghRows != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(prghRows);
}
}
}
private void PrimeIndexAndCacheWhereId()
{
var queryStr = QueryStringBuilder.GeneratePrimingQuery();
var rowset = ExecuteCommand(queryStr);
if (rowset != null)
{
if (reuseRowset != null)
{
Marshal.ReleaseComObject(reuseRowset);
}
reuseRowset = rowset;
reuseWhereID = GetReuseWhereId(reuseRowset);
}
}
private unsafe IRowset ExecuteCommand(string queryStr)
{
object sessionPtr = null;
object commandPtr = null;
try
{
var session = (IDBCreateSession)DataSourceManager.GetDataSource();
session.CreateSession(null, typeof(IDBCreateCommand).GUID, out sessionPtr);
if (sessionPtr == null)
{
Logger.LogError("CreateSession failed");
return null;
}
var createCommand = (IDBCreateCommand)sessionPtr;
createCommand.CreateCommand(null, typeof(ICommandText).GUID, out commandPtr);
if (commandPtr == null)
{
Logger.LogError("CreateCommand failed");
return null;
}
var commandText = (ICommandText)commandPtr;
if (commandText == null)
{
Logger.LogError("Failed to get ICommandText interface");
return null;
}
commandText.SetCommandText(in NativeHelpers.OleDb.DbGuidDefault, queryStr);
commandText.Execute(null, typeof(IRowset).GUID, null, null, out var rowsetPointer);
return rowsetPointer as IRowset;
}
catch (Exception ex)
{
Logger.LogError("Unexpected error.", ex);
return null;
}
finally
{
// Release the command pointer
if (commandPtr != null)
{
Marshal.ReleaseComObject(commandPtr);
}
// Release the session pointer
if (sessionPtr != null)
{
Marshal.ReleaseComObject(sessionPtr);
}
}
}
private IRowsetInfo GetRowsetInfo(IRowset rowset)
{
if (rowset == null)
{
return null;
}
var rowsetPtr = IntPtr.Zero;
var rowsetInfoPtr = IntPtr.Zero;
try
{
// Get the IUnknown pointer for the IRowset object
rowsetPtr = Marshal.GetIUnknownForObject(rowset);
// Query for IRowsetInfo interface
var rowsetInfoGuid = typeof(IRowsetInfo).GUID;
var res = Marshal.QueryInterface(rowsetPtr, in rowsetInfoGuid, out rowsetInfoPtr);
if (res != 0)
{
Logger.LogError($"Error getting IRowsetInfo interface: {res}");
return null;
}
// Marshal the interface pointer to the actual IRowsetInfo object
var rowsetInfo = (IRowsetInfo)Marshal.GetObjectForIUnknown(rowsetInfoPtr);
return rowsetInfo;
}
catch (Exception ex)
{
Logger.LogError($"Exception occurred while getting IRowsetInfo. ", ex);
return null;
}
finally
{
// Release the IRowsetInfo pointer if it was obtained
if (rowsetInfoPtr != IntPtr.Zero)
{
Marshal.Release(rowsetInfoPtr); // Release the IRowsetInfo pointer
}
// Release the IUnknown pointer for the IRowset object
if (rowsetPtr != IntPtr.Zero)
{
Marshal.Release(rowsetPtr);
}
}
}
private DBPROP? GetPropset(IRowsetInfo rowsetInfo)
{
var prgPropSetsPtr = IntPtr.Zero;
try
{
ulong cPropertySets;
var res = rowsetInfo.GetProperties(1, [dbPropIdSet], out cPropertySets, out prgPropSetsPtr);
if (res != 0)
{
Logger.LogError($"Error getting properties: {res}");
return null;
}
if (cPropertySets == 0 || prgPropSetsPtr == IntPtr.Zero)
{
Logger.LogError("No property sets returned");
return null;
}
var firstPropSetPtr = new IntPtr(prgPropSetsPtr.ToInt64());
var propSet = Marshal.PtrToStructure<DBPROPSET>(firstPropSetPtr);
if (propSet.cProperties == 0 || propSet.rgProperties == IntPtr.Zero)
{
return null;
}
var propPtr = new IntPtr(propSet.rgProperties.ToInt64());
var prop = Marshal.PtrToStructure<DBPROP>(propPtr);
return prop;
}
catch (Exception ex)
{
Logger.LogError($"Exception occurred while getting properties,", ex);
return null;
}
finally
{
// Free the property sets pointer returned by GetProperties, if necessary
if (prgPropSetsPtr != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(prgPropSetsPtr);
}
}
}
private uint GetReuseWhereId(IRowset rowset)
{
var rowsetInfo = GetRowsetInfo(rowset);
if (rowsetInfo == null)
{
return 0;
}
var prop = GetPropset(rowsetInfo);
if (prop == null)
{
return 0;
}
if (prop?.vValue.Anonymous.Anonymous.vt == VARENUM.VT_UI4)
{
var value = prop?.vValue.Anonymous.Anonymous.Anonymous.ulVal;
return (uint)value;
}
return 0;
}
public void Dispose()
{
CancelOutstandingQueries();
// Free the allocated memory for rgPropertyIDs
if (dbPropIdSet.rgPropertyIDs != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(dbPropIdSet.rgPropertyIDs);
}
if (reuseRowset != null)
{
Marshal.ReleaseComObject(reuseRowset);
reuseRowset = null;
}
if (currentRowset != null)
{
Marshal.ReleaseComObject(currentRowset);
currentRowset = null;
}
queryCompletedEvent?.Dispose();
}
}

View File

@@ -0,0 +1,96 @@
// 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 ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Indexer.Utils;
using Microsoft.CmdPal.Ext.Indexer.Native;
using Windows.Win32.System.Com;
using Windows.Win32.System.Com.StructuredStorage;
using Windows.Win32.UI.Shell.PropertiesSystem;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer;
internal sealed class SearchResult
{
public string ItemDisplayName { get; init; }
public string ItemUrl { get; init; }
public string LaunchUri { get; init; }
public bool IsFolder { get; init; }
public SearchResult(string name, string url, string filePath, bool isFolder)
{
ItemDisplayName = name;
ItemUrl = url;
IsFolder = isFolder;
if (LaunchUri == null || LaunchUri.Length == 0)
{
// Launch the file with the default app, so use the file path
LaunchUri = filePath;
}
}
public static unsafe SearchResult Create(IPropertyStore propStore)
{
try
{
var key = NativeHelpers.PropertyKeys.PKEYItemNameDisplay;
propStore.GetValue(&key, out var itemNameDisplay);
key = NativeHelpers.PropertyKeys.PKEYItemUrl;
propStore.GetValue(&key, out var itemUrl);
key = NativeHelpers.PropertyKeys.PKEYKindText;
propStore.GetValue(&key, out var kindText);
var filePath = GetFilePath(ref itemUrl);
var isFolder = IsFoder(ref kindText);
// Create the actual result object
var searchResult = new SearchResult(
GetStringFromPropVariant(ref itemNameDisplay),
GetStringFromPropVariant(ref itemUrl),
filePath,
isFolder);
return searchResult;
}
catch (Exception ex)
{
Logger.LogError("Failed to get property values from propStore.", ex);
return null;
}
}
private static bool IsFoder(ref PROPVARIANT kindText)
{
var kindString = GetStringFromPropVariant(ref kindText);
return string.Equals(kindString, "Folder", StringComparison.OrdinalIgnoreCase);
}
private static string GetFilePath(ref PROPVARIANT itemUrl)
{
var filePath = GetStringFromPropVariant(ref itemUrl);
filePath = UrlToFilePathConverter.Convert(filePath);
return filePath;
}
private static string GetStringFromPropVariant(ref PROPVARIANT propVariant)
{
if (propVariant.Anonymous.Anonymous.vt == VARENUM.VT_LPWSTR)
{
var pwszVal = propVariant.Anonymous.Anonymous.Anonymous.pwszVal;
if (pwszVal != null)
{
return pwszVal.ToString();
}
}
return string.Empty;
}
}

View File

@@ -0,0 +1,18 @@
// 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.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[CoClass(typeof(CSearchCatalogManagerClass))]
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF50")]
[ComImport]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1715:Identifiers should have correct prefix", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1302:Interface names should begin with I", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Using original name from type lib")]
public interface CSearchCatalogManager : ISearchCatalogManager
{
}

View File

@@ -0,0 +1,131 @@
// 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.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[ComConversionLoss]
[Guid("AAB49DD5-AD0B-40AE-B654-AE8976BF6BD2")]
[ClassInterface((short)0)]
[ComImport]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "The order of the property accessors must match the order in which the methods were defined in the vtable")]
public class CSearchCatalogManagerClass : ISearchCatalogManager, CSearchCatalogManager
{
[DispId(1610678272)]
public virtual extern string Name
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern IntPtr GetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void SetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName, [In] ref object pValue);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void GetCatalogStatus(
out object pStatus,
out object pPausedReason);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void Reset();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void Reindex();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void ReindexMatchingURLs([MarshalAs(UnmanagedType.LPWStr), In] string pszPattern);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void ReindexSearchRoot([MarshalAs(UnmanagedType.LPWStr), In] string pszRoot);
[DispId(1610678280)]
public virtual extern uint ConnectTimeout
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678282)]
public virtual extern uint DataTimeout
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern int NumberOfItems();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void NumberOfItemsToIndex(
out int plIncrementalCount,
out int plNotificationQueue,
out int plHighPriorityQueue);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public virtual extern string URLBeingIndexed();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern uint GetURLIndexingState([MarshalAs(UnmanagedType.LPWStr), In] string psz);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
public virtual extern object GetPersistentItemsChangedSink();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void RegisterViewForNotification(
[MarshalAs(UnmanagedType.LPWStr), In] string pszView,
[MarshalAs(UnmanagedType.Interface), In] object pViewChangedSink,
out uint pdwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void GetItemsChangedSink(
[MarshalAs(UnmanagedType.Interface), In] object pISearchNotifyInlineSite,
[In] ref Guid riid,
out IntPtr ppv,
out Guid pGUIDCatalogResetSignature,
out Guid pGUIDCheckPointSignature,
out uint pdwLastCheckPointNumber);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void UnregisterViewForNotification([In] uint dwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void SetExtensionClusion([MarshalAs(UnmanagedType.LPWStr), In] string pszExtension, [In] int fExclude);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
public virtual extern object EnumerateExcludedExtensions();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
public virtual extern CSearchQueryHelper GetQueryHelper();
[DispId(1610678295)]
public virtual extern int DiacriticSensitivity
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
public virtual extern object GetCrawlScopeManager();
}

View File

@@ -0,0 +1,18 @@
// 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.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[CoClass(typeof(CSearchManagerClass))]
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF69")]
[ComImport]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1715:Identifiers should have correct prefix", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1302:Interface names should begin with I", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Using original name from type lib")]
public interface CSearchManager : ISearchManager
{
}

View File

@@ -0,0 +1,90 @@
// 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.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[Guid("7D096C5F-AC08-4F1F-BEB7-5C22C517CE39")]
[TypeLibType(2)]
[ClassInterface((short)0)]
[ComConversionLoss]
[ComImport]
public class CSearchManagerClass : ISearchManager, CSearchManager
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void GetIndexerVersionStr([MarshalAs(UnmanagedType.LPWStr)] out string ppszVersionString);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void GetIndexerVersion(out uint pdwMajor, out uint pdwMinor);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern IntPtr GetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void SetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName, [In] ref object pValue);
[DispId(1610678276)]
public virtual extern string ProxyName
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678277)]
public virtual extern string BypassList
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void SetProxy(
[In] object sUseProxy,
[In] int fLocalByPassProxy,
[In] uint dwPortNumber,
[MarshalAs(UnmanagedType.LPWStr), In] string pszProxyName,
[MarshalAs(UnmanagedType.LPWStr), In] string pszByPassList);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
public virtual extern CSearchCatalogManager GetCatalog([MarshalAs(UnmanagedType.LPWStr), In] string pszCatalog);
[DispId(1610678280)]
public virtual extern string UserAgent
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
}
[DispId(1610678282)]
public virtual extern object UseProxy
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678283)]
public virtual extern int LocalBypass
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678284)]
public virtual extern uint PortNumber
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
}

View File

@@ -0,0 +1,18 @@
// 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.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF63")]
[CoClass(typeof(CSearchQueryHelperClass))]
[ComImport]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1715:Identifiers should have correct prefix", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1302:Interface names should begin with I", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Using original name from type lib")]
public interface CSearchQueryHelper : ISearchQueryHelper
{
}

View File

@@ -0,0 +1,134 @@
// 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.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[ClassInterface((short)0)]
[Guid("B271E955-09E1-42E1-9B95-5994A534B613")]
[ComImport]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "The order of the property accessors must match the order in which the methods were defined in the vtable")]
public class CSearchQueryHelperClass : ISearchQueryHelper, CSearchQueryHelper
{
[DispId(1610678272)]
public virtual extern string ConnectionString
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678273)]
public virtual extern uint QueryContentLocale
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678275)]
public virtual extern uint QueryKeywordLocale
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678277)]
public virtual extern object QueryTermExpansion
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678279)]
public virtual extern object QuerySyntax
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678281)]
public virtual extern string QueryContentProperties
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678283)]
public virtual extern string QuerySelectColumns
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678285)]
public virtual extern string QueryWhereRestrictions
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678287)]
public virtual extern string QuerySorting
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public virtual extern string GenerateSQLFromUserQuery([MarshalAs(UnmanagedType.LPWStr), In] string pszQuery);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void WriteProperties(
[In] int itemID,
[In] uint dwNumberOfColumns,
[In] ref object pColumns,
[In] ref object pValues,
[In] ref object pftGatherModifiedTime);
[DispId(1610678291)]
public virtual extern int QueryMaxResults
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
}

View File

@@ -0,0 +1,129 @@
// 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.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF50")]
[ComConversionLoss]
[InterfaceType(1)]
[ComImport]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "The order of the property accessors must match the order in which the methods were defined in the vtable")]
public interface ISearchCatalogManager
{
[DispId(1610678272)]
string Name
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
IntPtr GetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName, [In] ref object pValue);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCatalogStatus(out object pStatus, out object pPausedReason);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Reset();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Reindex();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ReindexMatchingURLs([MarshalAs(UnmanagedType.LPWStr), In] string pszPattern);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ReindexSearchRoot([MarshalAs(UnmanagedType.LPWStr), In] string pszRoot);
[DispId(1610678280)]
uint ConnectTimeout
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678282)]
uint DataTimeout
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
int NumberOfItems();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void NumberOfItemsToIndex(
out int plIncrementalCount,
out int plNotificationQueue,
out int plHighPriorityQueue);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
string URLBeingIndexed();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
uint GetURLIndexingState([MarshalAs(UnmanagedType.LPWStr), In] string psz);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
object GetPersistentItemsChangedSink();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void RegisterViewForNotification(
[MarshalAs(UnmanagedType.LPWStr), In] string pszView,
[MarshalAs(UnmanagedType.Interface), In] object pViewChangedSink,
out uint pdwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetItemsChangedSink(
[MarshalAs(UnmanagedType.Interface), In] object pISearchNotifyInlineSite,
[In] ref Guid riid,
out IntPtr ppv,
out Guid pGUIDCatalogResetSignature,
out Guid pGUIDCheckPointSignature,
out uint pdwLastCheckPointNumber);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void UnregisterViewForNotification([In] uint dwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetExtensionClusion([MarshalAs(UnmanagedType.LPWStr), In] string pszExtension, [In] int fExclude);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
object EnumerateExcludedExtensions();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
CSearchQueryHelper GetQueryHelper();
[DispId(1610678295)]
int DiacriticSensitivity
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
object GetCrawlScopeManager();
}

View File

@@ -0,0 +1,89 @@
// 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.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[ComConversionLoss]
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF69")]
[InterfaceType(1)]
[ComImport]
public interface ISearchManager
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetIndexerVersionStr([MarshalAs(UnmanagedType.LPWStr)] out string ppszVersionString);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetIndexerVersion(out uint pdwMajor, out uint pdwMinor);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
IntPtr GetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName, [In] ref object pValue);
[DispId(1610678276)]
string ProxyName
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678277)]
string BypassList
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetProxy(
[In] object sUseProxy,
[In] int fLocalByPassProxy,
[In] uint dwPortNumber,
[MarshalAs(UnmanagedType.LPWStr), In] string pszProxyName,
[MarshalAs(UnmanagedType.LPWStr), In] string pszByPassList);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
CSearchCatalogManager GetCatalog([MarshalAs(UnmanagedType.LPWStr), In] string pszCatalog);
[DispId(1610678280)]
string UserAgent
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
}
[DispId(1610678282)]
object UseProxy
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678283)]
int LocalBypass
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678284)]
uint PortNumber
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
}

View File

@@ -0,0 +1,134 @@
// 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.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF63")]
[InterfaceType(1)]
[ComImport]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "The order of the property accessors must match the order in which the methods were defined in the vtable")]
public interface ISearchQueryHelper
{
[DispId(1610678272)]
string ConnectionString
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678273)]
uint QueryContentLocale
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678275)]
uint QueryKeywordLocale
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678277)]
object QueryTermExpansion
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678279)]
object QuerySyntax
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678281)]
string QueryContentProperties
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678283)]
string QuerySelectColumns
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678285)]
string QueryWhereRestrictions
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678287)]
string QuerySorting
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
string GenerateSQLFromUserQuery([MarshalAs(UnmanagedType.LPWStr), In] string pszQuery);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void WriteProperties(
[In] int itemID,
[In] uint dwNumberOfColumns,
[In] ref object pColumns,
[In] ref object pValues,
[In] ref object pftGatherModifiedTime);
[DispId(1610678291)]
int QueryMaxResults
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
}

View File

@@ -0,0 +1,39 @@
// 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.Globalization;
using Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.Utils;
internal sealed class QueryStringBuilder
{
private const string Properties = "System.ItemUrl, System.ItemNameDisplay, path, System.Search.EntryID, System.Kind, System.KindText";
private const string SystemIndex = "SystemIndex";
private const string ScopeFileConditions = "SCOPE='file:'";
private const string OrderConditions = "System.DateModified DESC";
private const string SelectQueryWithScope = "SELECT " + Properties + " FROM " + SystemIndex + " WHERE (" + ScopeFileConditions + ")";
private const string SelectQueryWithScopeAndOrderConditions = SelectQueryWithScope + " ORDER BY " + OrderConditions;
private static ISearchQueryHelper queryHelper;
public static string GeneratePrimingQuery() => SelectQueryWithScopeAndOrderConditions;
public static string GenerateQuery(string searchText, uint whereId)
{
if (queryHelper == null)
{
var searchManager = new CSearchManager();
ISearchCatalogManager catalogManager = searchManager.GetCatalog(SystemIndex);
queryHelper = catalogManager.GetQueryHelper();
queryHelper.QuerySelectColumns = Properties;
queryHelper.QueryContentProperties = "System.FileName";
queryHelper.QuerySorting = OrderConditions;
}
queryHelper.QueryWhereRestrictions = "AND " + ScopeFileConditions + "AND ReuseWhere(" + whereId.ToString(CultureInfo.InvariantCulture) + ")";
return queryHelper.GenerateSQLFromUserQuery(searchText);
}
}

View File

@@ -0,0 +1,25 @@
// 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;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.Utils;
public class UrlToFilePathConverter
{
public static string Convert(string url)
{
var result = url.Replace('/', '\\'); // replace all '/' to '\'
var fileProtocolString = "file:";
var indexProtocolFound = url.IndexOf(fileProtocolString, StringComparison.CurrentCultureIgnoreCase);
if (indexProtocolFound != -1 && (indexProtocolFound + fileProtocolString.Length) < url.Length)
{
result = result[(indexProtocolFound + fileProtocolString.Length)..];
}
return result;
}
}

View File

@@ -0,0 +1,37 @@
// 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 Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Indexer;
public partial class IndexerCommandsProvider : CommandProvider
{
private readonly FallbackOpenFileItem _fallbackFileItem = new();
public IndexerCommandsProvider()
{
Id = "Files";
DisplayName = Resources.IndexerCommandsProvider_DisplayName;
Icon = Icons.FileExplorer;
}
public override ICommandItem[] TopLevelCommands()
{
return [
new CommandItem(new IndexerPage())
{
Title = Resources.Indexer_Title,
Subtitle = Resources.Indexer_Subtitle,
}
];
}
public override IFallbackCommandItem[] FallbackCommands() =>
[
_fallbackFileItem
];
}

View File

@@ -0,0 +1,49 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<RootNamespace>Microsoft.CmdPal.Ext.Indexer</RootNamespace>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWin32">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Remove="Assets\FileExplorer.svg" />
</ItemGroup>
<ItemGroup>
<Content Update="Assets\FileExplorer.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Assets\FileExplorer.svg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,25 @@
// 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 Windows.Win32.UI.Shell.PropertiesSystem;
namespace Microsoft.CmdPal.Ext.Indexer.Native;
internal sealed class NativeHelpers
{
public const uint SEEMASKINVOKEIDLIST = 12;
internal static class PropertyKeys
{
public static readonly PROPERTYKEY PKEYItemNameDisplay = new() { fmtid = new System.Guid("B725F130-47EF-101A-A5F1-02608C9EEBAC"), pid = 10 };
public static readonly PROPERTYKEY PKEYItemUrl = new() { fmtid = new System.Guid("49691C90-7E17-101A-A91C-08002B2ECDA9"), pid = 9 };
public static readonly PROPERTYKEY PKEYKindText = new() { fmtid = new System.Guid("F04BEF95-C585-4197-A2B7-DF46FDC9EE6D"), pid = 100 };
}
internal static class OleDb
{
public static readonly Guid DbGuidDefault = new("C8B521FB-5CF3-11CE-ADE5-00AA0044773D");
}
}

View File

@@ -0,0 +1,11 @@
DBID
SHOW_WINDOW_CMD
CoCreateInstance
GetErrorInfo
ICommandText
IDBCreateCommand
IDBCreateSession
IDBInitialize
IGetRow
IPropertyStore
ShellExecuteEx

View File

@@ -0,0 +1,151 @@
// 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.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Storage.Streams;
#nullable enable
namespace Microsoft.CmdPal.Ext.Indexer;
/// <summary>
/// This is almost more of just a sample than anything.
/// This is one singular page for switching.
/// </summary>
public sealed partial class DirectoryExplorePage : DynamicListPage
{
private string _path;
private List<ExploreListItem>? _directoryContents;
private List<ExploreListItem>? _filteredContents;
public DirectoryExplorePage(string path)
{
_path = path;
Icon = Icons.FileExplorer;
Name = Resources.Indexer_Command_Browse;
Title = path;
}
public override void UpdateSearchText(string oldSearch, string newSearch)
{
if (_directoryContents == null)
{
return;
}
if (string.IsNullOrEmpty(newSearch))
{
if (_filteredContents != null)
{
_filteredContents = null;
RaiseItemsChanged(-1);
}
return;
}
// Need to break this out the manual way so that the compiler can know
// this is an ExploreListItem
var filteredResults = ListHelpers.FilterList(
_directoryContents,
newSearch,
(s, i) => ListHelpers.ScoreListItem(s, i));
if (_filteredContents != null)
{
lock (_filteredContents)
{
ListHelpers.InPlaceUpdateList<ExploreListItem>(_filteredContents, filteredResults);
}
}
else
{
_filteredContents = filteredResults.ToList();
}
RaiseItemsChanged(-1);
}
public override IListItem[] GetItems()
{
if (_filteredContents != null)
{
return _filteredContents.ToArray();
}
if (_directoryContents != null)
{
return _directoryContents.ToArray();
}
IsLoading = true;
if (!Path.Exists(_path))
{
EmptyContent = new CommandItem(title: Resources.Indexer_File_Does_Not_Exist);
return [];
}
var attr = File.GetAttributes(_path);
// detect whether its a directory or file
if ((attr & FileAttributes.Directory) != FileAttributes.Directory)
{
EmptyContent = new CommandItem(title: Resources.Indexer_File_Is_File_Not_Folder);
return [];
}
var contents = Directory.EnumerateFileSystemEntries(_path);
_directoryContents = contents
.Select(s => new IndexerItem() { FullPath = s, FileName = Path.GetFileName(s) })
.Select(i => new ExploreListItem(i))
.ToList();
foreach (var i in _directoryContents)
{
i.PathChangeRequested += HandlePathChangeRequested;
}
_ = Task.Run(() =>
{
foreach (var item in _directoryContents)
{
IconInfo? icon = null;
try
{
var stream = ThumbnailHelper.GetThumbnail(item.FilePath).Result;
if (stream != null)
{
var data = new IconData(RandomAccessStreamReference.CreateFromStream(stream));
icon = new IconInfo(data, data);
}
}
catch
{
}
item.Icon = icon;
}
});
IsLoading = false;
return _directoryContents.ToArray();
}
private void HandlePathChangeRequested(ExploreListItem sender, string path)
{
_directoryContents = null;
_filteredContents = null;
_path = path;
Title = path;
SearchText = string.Empty;
RaiseItemsChanged(-1);
}
}

View File

@@ -0,0 +1,105 @@
// 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.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Storage.Streams;
#nullable enable
namespace Microsoft.CmdPal.Ext.Indexer;
public sealed partial class DirectoryPage : ListPage
{
private readonly string _path;
private List<IndexerListItem>? _directoryContents;
public DirectoryPage(string path)
{
_path = path;
Icon = Icons.FileExplorer;
Name = Resources.Indexer_Command_Browse;
Title = path;
}
public override IListItem[] GetItems()
{
if (_directoryContents != null)
{
return _directoryContents.ToArray();
}
if (!Path.Exists(_path))
{
EmptyContent = new CommandItem(
title: Resources.Indexer_File_Does_Not_Exist,
subtitle: $"{_path}");
return [];
}
var attr = File.GetAttributes(_path);
// detect whether its a directory or file
if ((attr & FileAttributes.Directory) != FileAttributes.Directory)
{
EmptyContent = new CommandItem(
title: Resources.Indexer_File_Is_File_Not_Folder, subtitle: $"{_path}")
{
Icon = Icons.Document,
};
return [];
}
var contents = Directory.EnumerateFileSystemEntries(_path);
if (!contents.Any())
{
var item = new IndexerItem() { FullPath = _path, FileName = Path.GetFileName(_path) };
var listItemForUs = new IndexerListItem(item, IncludeBrowseCommand.Exclude);
EmptyContent = new CommandItem(
title: Resources.Indexer_Folder_Is_Empty, subtitle: $"{_path}")
{
Icon = Icons.FolderOpen,
Command = listItemForUs.Command,
MoreCommands = listItemForUs.MoreCommands,
};
return [];
}
_directoryContents = contents
.Select(s => new IndexerItem() { FullPath = s, FileName = Path.GetFileName(s) })
.Select(i => new IndexerListItem(i, IncludeBrowseCommand.AsDefault))
.ToList();
_ = Task.Run(() =>
{
foreach (var item in _directoryContents)
{
IconInfo? icon = null;
try
{
var stream = ThumbnailHelper.GetThumbnail(item.FilePath).Result;
if (stream != null)
{
var data = new IconData(RandomAccessStreamReference.CreateFromStream(stream));
icon = new IconInfo(data, data);
}
}
catch
{
}
item.Icon = icon;
}
});
return _directoryContents.ToArray();
}
}

View File

@@ -0,0 +1,56 @@
// 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.CmdPal.Ext.Indexer.Commands;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Foundation;
#nullable enable
namespace Microsoft.CmdPal.Ext.Indexer;
/// <summary>
/// This is almost more of just a sample than anything.
/// </summary>
internal sealed partial class ExploreListItem : ListItem
{
internal string FilePath { get; private set; }
internal event TypedEventHandler<ExploreListItem, string>? PathChangeRequested;
public ExploreListItem(IndexerItem indexerItem)
: base(new NoOpCommand())
{
FilePath = indexerItem.FullPath;
Title = indexerItem.FileName;
Subtitle = indexerItem.FullPath;
List<CommandContextItem> context = [];
if (indexerItem.IsDirectory())
{
Command = new AnonymousCommand(
() => { PathChangeRequested?.Invoke(this, FilePath); })
{
Result = CommandResult.KeepOpen(),
Name = Resources.Indexer_Command_Browse,
};
context.Add(new CommandContextItem(new DirectoryPage(indexerItem.FullPath)));
}
else
{
Command = new OpenFileCommand(indexerItem);
}
MoreCommands = [
..context,
new CommandContextItem(new OpenWithCommand(indexerItem)),
new CommandContextItem(new ShowFileInFolderCommand(indexerItem.FullPath) { Name = Resources.Indexer_Command_ShowInFolder }),
new CommandContextItem(new CopyPathCommand(indexerItem)),
new CommandContextItem(new OpenInConsoleCommand(indexerItem)),
new CommandContextItem(new OpenPropertiesCommand(indexerItem)),
];
}
}

View File

@@ -0,0 +1,20 @@
// 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 Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Indexer;
internal sealed class Icons
{
internal static IconInfo FileExplorerSegoe { get; } = new("\uEC50");
internal static IconInfo FileExplorer { get; } = IconHelpers.FromRelativePath("Assets\\FileExplorer.png");
internal static IconInfo OpenFile { get; } = new("\uE8E5"); // OpenFile
internal static IconInfo Document { get; } = new("\uE8A5"); // Document
internal static IconInfo FolderOpen { get; } = new("\uE838"); // FolderOpen
}

View File

@@ -0,0 +1,127 @@
// 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.Diagnostics;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Indexer;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Storage.Streams;
namespace Microsoft.CmdPal.Ext.Indexer;
internal sealed partial class IndexerPage : DynamicListPage, IDisposable
{
private readonly List<IListItem> _indexerListItems = [];
private SearchQuery _searchQuery = new();
private uint _queryCookie = 10;
public IndexerPage()
{
Id = "com.microsoft.indexer.fileSearch";
Icon = Icons.FileExplorer;
Name = Resources.Indexer_Title;
PlaceholderText = Resources.Indexer_PlaceholderText;
}
public override void UpdateSearchText(string oldSearch, string newSearch)
{
if (oldSearch != newSearch)
{
_ = Task.Run(() =>
{
Query(newSearch);
LoadMore();
});
}
}
public override IListItem[] GetItems() => [.. _indexerListItems];
public override void LoadMore()
{
IsLoading = true;
FetchItems(20);
IsLoading = false;
RaiseItemsChanged(_indexerListItems.Count);
}
private void Query(string query)
{
++_queryCookie;
_indexerListItems.Clear();
_searchQuery.SearchResults.Clear();
_searchQuery.CancelOutstandingQueries();
if (query == string.Empty)
{
return;
}
Stopwatch stopwatch = new();
stopwatch.Start();
_searchQuery.Execute(query, _queryCookie);
stopwatch.Stop();
Logger.LogDebug($"Query time: {stopwatch.ElapsedMilliseconds} ms, query: \"{query}\"");
}
private void FetchItems(int limit)
{
if (_searchQuery != null)
{
var cookie = _searchQuery.Cookie;
if (cookie == _queryCookie)
{
var index = 0;
SearchResult result;
var hasMoreItems = _searchQuery.FetchRows(_indexerListItems.Count, limit);
while (!_searchQuery.SearchResults.IsEmpty && _searchQuery.SearchResults.TryDequeue(out result) && ++index <= limit)
{
IconInfo icon = null;
try
{
var stream = ThumbnailHelper.GetThumbnail(result.LaunchUri).Result;
if (stream != null)
{
var data = new IconData(RandomAccessStreamReference.CreateFromStream(stream));
icon = new IconInfo(data, data);
}
}
catch (Exception ex)
{
Logger.LogError("Failed to get the icon.", ex);
}
_indexerListItems.Add(new IndexerListItem(new IndexerItem
{
FileName = result.ItemDisplayName,
FullPath = result.LaunchUri,
})
{
Icon = icon,
});
}
HasMoreItems = hasMoreItems;
}
}
}
public void Dispose()
{
_searchQuery = null;
GC.SuppressFinalize(this);
}
}

View File

@@ -0,0 +1,198 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Microsoft.CmdPal.Ext.Indexer.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.CmdPal.Ext.Indexer.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Browse.
/// </summary>
internal static string Indexer_Command_Browse {
get {
return ResourceManager.GetString("Indexer_Command_Browse", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Copy path.
/// </summary>
internal static string Indexer_Command_CopyPath {
get {
return ResourceManager.GetString("Indexer_Command_CopyPath", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open.
/// </summary>
internal static string Indexer_Command_OpenFile {
get {
return ResourceManager.GetString("Indexer_Command_OpenFile", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open path in console.
/// </summary>
internal static string Indexer_Command_OpenPathInConsole {
get {
return ResourceManager.GetString("Indexer_Command_OpenPathInConsole", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Properties.
/// </summary>
internal static string Indexer_Command_OpenProperties {
get {
return ResourceManager.GetString("Indexer_Command_OpenProperties", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open with.
/// </summary>
internal static string Indexer_Command_OpenWith {
get {
return ResourceManager.GetString("Indexer_Command_OpenWith", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show in folder.
/// </summary>
internal static string Indexer_Command_ShowInFolder {
get {
return ResourceManager.GetString("Indexer_Command_ShowInFolder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This file doesn&apos;t exist.
/// </summary>
internal static string Indexer_File_Does_Not_Exist {
get {
return ResourceManager.GetString("Indexer_File_Does_Not_Exist", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This is a file, not a folder.
/// </summary>
internal static string Indexer_File_Is_File_Not_Folder {
get {
return ResourceManager.GetString("Indexer_File_Is_File_Not_Folder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Find file from path.
/// </summary>
internal static string Indexer_Find_Path_fallback_display_title {
get {
return ResourceManager.GetString("Indexer_Find_Path_fallback_display_title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This folder is empty.
/// </summary>
internal static string Indexer_Folder_Is_Empty {
get {
return ResourceManager.GetString("Indexer_Folder_Is_Empty", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Search for files and folders....
/// </summary>
internal static string Indexer_PlaceholderText {
get {
return ResourceManager.GetString("Indexer_PlaceholderText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Search files on this device.
/// </summary>
internal static string Indexer_Subtitle {
get {
return ResourceManager.GetString("Indexer_Subtitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Search files.
/// </summary>
internal static string Indexer_Title {
get {
return ResourceManager.GetString("Indexer_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File search.
/// </summary>
internal static string IndexerCommandsProvider_DisplayName {
get {
return ResourceManager.GetString("IndexerCommandsProvider_DisplayName", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,165 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="IndexerCommandsProvider_DisplayName" xml:space="preserve">
<value>File search</value>
</data>
<data name="Indexer_Command_Browse" xml:space="preserve">
<value>Browse</value>
</data>
<data name="Indexer_Command_CopyPath" xml:space="preserve">
<value>Copy path</value>
</data>
<data name="Indexer_Command_OpenFile" xml:space="preserve">
<value>Open</value>
</data>
<data name="Indexer_Command_OpenPathInConsole" xml:space="preserve">
<value>Open path in console</value>
</data>
<data name="Indexer_Command_OpenProperties" xml:space="preserve">
<value>Properties</value>
</data>
<data name="Indexer_Command_OpenWith" xml:space="preserve">
<value>Open with</value>
</data>
<data name="Indexer_Command_ShowInFolder" xml:space="preserve">
<value>Show in folder</value>
</data>
<data name="Indexer_File_Does_Not_Exist" xml:space="preserve">
<value>This file doesn't exist</value>
</data>
<data name="Indexer_File_Is_File_Not_Folder" xml:space="preserve">
<value>This is a file, not a folder</value>
</data>
<data name="Indexer_Find_Path_fallback_display_title" xml:space="preserve">
<value>Find file from path</value>
</data>
<data name="Indexer_Folder_Is_Empty" xml:space="preserve">
<value>This folder is empty</value>
</data>
<data name="Indexer_PlaceholderText" xml:space="preserve">
<value>Search for files and folders...</value>
</data>
<data name="Indexer_Subtitle" xml:space="preserve">
<value>Search files on this device</value>
</data>
<data name="Indexer_Title" xml:space="preserve">
<value>Search files</value>
</data>
</root>