290 lines
6.8 KiB
C#
290 lines
6.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using AxCopilot.SDK;
|
|
using AxCopilot.Services;
|
|
|
|
namespace AxCopilot.Handlers;
|
|
|
|
public class EverythingHandler : IActionHandler
|
|
{
|
|
private const int EVERYTHING_OK = 0;
|
|
|
|
private const int EVERYTHING_REQUEST_FILE_NAME = 1;
|
|
|
|
private const int EVERYTHING_REQUEST_PATH = 2;
|
|
|
|
private const int EVERYTHING_REQUEST_SIZE = 16;
|
|
|
|
private bool? _isAvailable;
|
|
|
|
public string? Prefix => "es";
|
|
|
|
public PluginMetadata Metadata => new PluginMetadata("EverythingSearch", "Everything 초고속 파일 검색 — es [키워드]", "1.0", "AX");
|
|
|
|
private bool IsAvailable
|
|
{
|
|
get
|
|
{
|
|
if (_isAvailable.HasValue)
|
|
{
|
|
return _isAvailable.Value;
|
|
}
|
|
try
|
|
{
|
|
Everything_GetMajorVersion();
|
|
_isAvailable = true;
|
|
}
|
|
catch
|
|
{
|
|
_isAvailable = false;
|
|
}
|
|
return _isAvailable.Value;
|
|
}
|
|
}
|
|
|
|
[DllImport("Everything64.dll", CharSet = CharSet.Unicode)]
|
|
private static extern uint Everything_SetSearchW(string lpSearchString);
|
|
|
|
[DllImport("Everything64.dll")]
|
|
private static extern void Everything_SetMax(uint dwMax);
|
|
|
|
[DllImport("Everything64.dll")]
|
|
private static extern void Everything_SetRequestFlags(uint dwRequestFlags);
|
|
|
|
[DllImport("Everything64.dll")]
|
|
private static extern bool Everything_QueryW(bool bWait);
|
|
|
|
[DllImport("Everything64.dll")]
|
|
private static extern uint Everything_GetNumResults();
|
|
|
|
[DllImport("Everything64.dll")]
|
|
private static extern uint Everything_GetLastError();
|
|
|
|
[DllImport("Everything64.dll", CharSet = CharSet.Unicode)]
|
|
private static extern nint Everything_GetResultFullPathNameW(uint nIndex, nint lpString, uint nMaxCount);
|
|
|
|
[DllImport("Everything64.dll", CharSet = CharSet.Unicode)]
|
|
private static extern void Everything_GetResultSize(uint nIndex, out long lpFileSize);
|
|
|
|
[DllImport("Everything64.dll")]
|
|
private static extern uint Everything_GetMajorVersion();
|
|
|
|
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
|
{
|
|
if (!IsAvailable)
|
|
{
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new LauncherItem[1]
|
|
{
|
|
new LauncherItem("Everything이 설치되어 있지 않습니다", "voidtools.com에서 Everything을 설치하면 초고속 파일 검색을 사용할 수 있습니다", null, null, null, "\ue7ba")
|
|
});
|
|
}
|
|
string text = query.Trim();
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
{
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new LauncherItem[1]
|
|
{
|
|
new LauncherItem("Everything 파일 검색", "검색어를 입력하세요 — 파일명, 확장자(*.xlsx), 경로 일부 등", null, null, null, "\ue721")
|
|
});
|
|
}
|
|
try
|
|
{
|
|
Everything_SetSearchW(text);
|
|
Everything_SetMax(30u);
|
|
Everything_SetRequestFlags(19u);
|
|
if (!Everything_QueryW(bWait: true))
|
|
{
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new LauncherItem[1]
|
|
{
|
|
new LauncherItem("Everything 검색 실패", $"오류 코드: {Everything_GetLastError()} — Everything 서비스가 실행 중인지 확인하세요", null, null, null, "\ue7ba")
|
|
});
|
|
}
|
|
uint num = Everything_GetNumResults();
|
|
if (num == 0)
|
|
{
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new LauncherItem[1]
|
|
{
|
|
new LauncherItem("검색 결과 없음: " + text, "다른 키워드나 와일드카드(*.xlsx)를 시도해 보세요", null, null, null, "\ue946")
|
|
});
|
|
}
|
|
List<LauncherItem> list = new List<LauncherItem>();
|
|
nint num2 = Marshal.AllocHGlobal(1040);
|
|
try
|
|
{
|
|
for (uint num3 = 0u; num3 < num && num3 < 30; num3++)
|
|
{
|
|
Everything_GetResultFullPathNameW(num3, num2, 520u);
|
|
string text2 = Marshal.PtrToStringUni(num2) ?? "";
|
|
Everything_GetResultSize(num3, out var lpFileSize);
|
|
string fileName = Path.GetFileName(text2);
|
|
string text3 = Path.GetDirectoryName(text2) ?? "";
|
|
string text4 = ((lpFileSize > 0) ? FormatSize(lpFileSize) : "");
|
|
string subtitle = (string.IsNullOrEmpty(text4) ? text3 : (text4 + " · " + text3));
|
|
string symbol = (Directory.Exists(text2) ? "\ue8b7" : GetFileSymbol(text2));
|
|
list.Add(new LauncherItem(fileName, subtitle, null, text2, null, symbol));
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Marshal.FreeHGlobal(num2);
|
|
}
|
|
return Task.FromResult((IEnumerable<LauncherItem>)list);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn("Everything 검색 오류: " + ex.Message);
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new LauncherItem[1]
|
|
{
|
|
new LauncherItem("Everything 검색 오류", ex.Message, null, null, null, "\ue7ba")
|
|
});
|
|
}
|
|
}
|
|
|
|
public async Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
|
{
|
|
object data = item.Data;
|
|
string path = data as string;
|
|
if (path == null || string.IsNullOrEmpty(path))
|
|
{
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
if (Directory.Exists(path))
|
|
{
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = path,
|
|
UseShellExecute = true
|
|
});
|
|
}
|
|
else if (File.Exists(path))
|
|
{
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = path,
|
|
UseShellExecute = true
|
|
});
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Exception ex2 = ex;
|
|
LogService.Warn("Everything 결과 열기 실패: " + ex2.Message);
|
|
}
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
private static string FormatSize(long bytes)
|
|
{
|
|
if (bytes >= 1024)
|
|
{
|
|
if (bytes >= 1048576)
|
|
{
|
|
if (bytes >= 1073741824)
|
|
{
|
|
return $"{(double)bytes / 1073741824.0:F2} GB";
|
|
}
|
|
return $"{(double)bytes / 1048576.0:F1} MB";
|
|
}
|
|
return $"{(double)bytes / 1024.0:F1} KB";
|
|
}
|
|
return $"{bytes} B";
|
|
}
|
|
|
|
private static string GetFileSymbol(string path)
|
|
{
|
|
string text = Path.GetExtension(path).ToLowerInvariant();
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
string result;
|
|
switch (text)
|
|
{
|
|
case ".xlsx":
|
|
case ".xls":
|
|
case ".csv":
|
|
result = "\ue9f9";
|
|
break;
|
|
case ".docx":
|
|
case ".doc":
|
|
result = "\ue8a5";
|
|
break;
|
|
case ".pptx":
|
|
case ".ppt":
|
|
result = "\uee71";
|
|
break;
|
|
case ".pdf":
|
|
result = "\uea90";
|
|
break;
|
|
case ".png":
|
|
case ".jpg":
|
|
case ".jpeg":
|
|
case ".gif":
|
|
case ".bmp":
|
|
case ".svg":
|
|
result = "\ueb9f";
|
|
break;
|
|
case ".mp4":
|
|
case ".avi":
|
|
case ".mkv":
|
|
case ".mov":
|
|
result = "\ue714";
|
|
break;
|
|
case ".mp3":
|
|
case ".wav":
|
|
case ".flac":
|
|
result = "\uec4f";
|
|
break;
|
|
case ".zip":
|
|
case ".rar":
|
|
case ".7z":
|
|
case ".tar":
|
|
case ".gz":
|
|
result = "\ue8c6";
|
|
break;
|
|
case ".exe":
|
|
case ".msi":
|
|
result = "\uecaa";
|
|
break;
|
|
case ".cs":
|
|
case ".py":
|
|
case ".js":
|
|
case ".ts":
|
|
case ".java":
|
|
case ".cpp":
|
|
case ".c":
|
|
case ".go":
|
|
result = "\ue943";
|
|
break;
|
|
case ".json":
|
|
case ".xml":
|
|
case ".yaml":
|
|
case ".yml":
|
|
result = "\ue713";
|
|
break;
|
|
case ".txt":
|
|
case ".md":
|
|
case ".log":
|
|
result = "\ue8d2";
|
|
break;
|
|
case ".html":
|
|
case ".htm":
|
|
case ".css":
|
|
result = "\ue774";
|
|
break;
|
|
default:
|
|
result = "\ue8a5";
|
|
break;
|
|
}
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
return result;
|
|
}
|
|
}
|