用过 Everything 也好一阵子了,一直以来都对他的快速搜寻有相当深刻的印象,但也只限于当作搜寻的工具之用,看了保哥介绍好用工具:Everything search engine (文件名搜寻工具) 的这篇,发现原来该套软件也有 SDK 可以使用,可借由他的强大搜寻功能用来开发自己的工具,花点时间试着玩了一下,顺手记录一下。
SDK 可在 Download Everything 这边下载,内含 C 与 C# 的范例程序、DLL 档、以及 C 开发要用的标头档之类的文件。Everything 提供的是 IPC 类型的 API,API 的使用可参阅 SDK - Wiki。这边需注意到由于是 IPC 类型的 API,故在使用时需确保 Everything 程序有被开启。另外就是要确认 SDK 内的 dllEverything.dll 是否有跟自己开发的程序放在一起。
为方便使用,这边我又将 API 包了一层,除了一些控制搜寻的属性外,最主要的就是 Search 方法,可提供搜寻我们所感兴趣的数据:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace Everything
{
///
/// ///
public class EverythingAPI
{
#region Const
const string EVERYTHING_DLL_NAME = "Everything.dll";
#endregion
#region DllImport
[DllImport(EVERYTHING_DLL_NAME)]
private static extern int Everything_SetSearch(string lpSearchString);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern void Everything_SetMatchPath(bool bEnable);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern void Everything_SetMatchCase(bool bEnable);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern void Everything_SetMatchWholeWord(bool bEnable);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern void Everything_SetRegex(bool bEnable);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern void Everything_SetMax(int dwMax);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern void Everything_SetOffset(int dwOffset);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern bool Everything_GetMatchPath();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern bool Everything_GetMatchCase();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern bool Everything_GetMatchWholeWord();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern bool Everything_GetRegex();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern UInt32 Everything_GetMax();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern UInt32 Everything_GetOffset();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern string Everything_GetSearch();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern StateCode Everything_GetLastError();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern bool Everything_Query();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern void Everything_SortResultsByPath();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern int Everything_GetNumFileResults();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern int Everything_GetNumFolderResults();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern int Everything_GetNumResults();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern int Everything_GetTotFileResults();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern int Everything_GetTotFolderResults();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern int Everything_GetTotResults();
[DllImport(EVERYTHING_DLL_NAME)]
private static extern bool Everything_IsVolumeResult(int nIndex);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern bool Everything_IsFolderResult(int nIndex);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern bool Everything_IsFileResult(int nIndex);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern void Everything_GetResultFullPathName(int nIndex, StringBuilder lpString, int nMaxCount);
[DllImport(EVERYTHING_DLL_NAME)]
private static extern void Everything_Reset();
#endregion
#region Enum
enum StateCode
{
OK,
MemoryError,
IPCError,
RegisterClassExError,
CreateWindowError,
CreateThreadError,
InvalidIndexError,
InvalidCallError
}
#endregion
#region Property
///
/// Gets or sets a value indicating whether [match path].
///
/// true if [match path]; otherwise, false.
public Boolean MatchPath {
get
{
return Everything_GetMatchPath();
}
set
{
Everything_SetMatchPath(value);
}
}
///
/// Gets or sets a value indicating whether [match case].
///
/// true if [match case]; otherwise, false.
public Boolean MatchCase {
get
{
return Everything_GetMatchCase();
}
set
{
Everything_SetMatchCase(value);
}
}
///
/// Gets or sets a value indicating whether [match whole word].
///
/// true if [match whole word]; otherwise, false.
public Boolean MatchWholeWord {
get
{
return Everything_GetMatchWholeWord();
}
set
{
Everything_SetMatchWholeWord(value);
}
}
///
/// Gets or sets a value indicating whether [enable regex].
///
/// true if [enable regex]; otherwise, false.
public Boolean EnableRegex {
get
{
return Everything_GetRegex();
}
set
{
Everything_SetRegex(value);
}
}
#endregion
#region Public Method
///
/// Resets this instance.
///
public void Reset()
{
Everything_Reset();
}
///
/// Searches the specified key word.
///
/// The key word.
///
public IEnumerable Search(string keyWord)
{
return Search(keyWord, 0, int.MaxValue);
}
///
/// Searches the specified key word.
///
/// The key word.
/// The offset.
/// The max count.
///
public IEnumerable Search(string keyWord,int offset,int maxCount)
{
if (string.IsNullOrEmpty(keyWord))
throw new ArgumentNullException("keyWord");
if (offset < 0)
throw new ArgumentOutOfRangeException("offset");
if (maxCount < 0)
throw new ArgumentOutOfRangeException("maxCount");
Everything_SetSearch(keyWord);
Everything_SetOffset(offset);
Everything_SetMax(maxCount);
if (!Everything_Query())
{
switch (Everything_GetLastError())
{
case StateCode.CreateThreadError:
throw new CreateThreadException();
case StateCode.CreateWindowError:
throw new CreateWindowException();
case StateCode.InvalidCallError:
throw new InvalidCallException();
case StateCode.InvalidIndexError:
throw new InvalidIndexException();
case StateCode.IPCError:
throw new IPCErrorException();
case StateCode.MemoryError:
throw new MemoryErrorException();
case StateCode.RegisterClassExError:
throw new RegisterClassExException();
}
yield break;
}
const int bufferSize = 256;
StringBuilder buffer = new StringBuilder(bufferSize);
for (int idx = 0; idx < Everything_GetNumResults(); ++idx)
{
Everything_GetResultFullPathName(idx, buffer, bufferSize);
yield return buffer.ToString();
}
}
#endregion
}
///
/// ///
public class MemoryErrorException:ApplicationException {
}
///
/// ///
public class IPCErrorException : ApplicationException
{
}
///
/// ///
public class RegisterClassExException : ApplicationException
{
}
///
/// ///
public class CreateWindowException : ApplicationException
{
}
///
/// ///
public class CreateThreadException : ApplicationException
{
}
///
/// ///
public class InvalidIndexException : ApplicationException
{
}
///
/// ///
public class InvalidCallException : ApplicationException
{
}
}
使用上会像这个样子:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Linq;
using Everything;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
EverythingAPI everyThingAPI = new EverythingAPI();
var results = everyThingAPI.Search(textBox1.Text);
Text = textBox1.Text + " - " + results.Count() + " Results";
listBox1.Items.Clear();
foreach (var item in results)
{
listBox1.Items.Add(item);
}
}
}
}