150 lines
3.9 KiB
C#
150 lines
3.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using AxCopilot.SDK;
|
|
using AxCopilot.Services;
|
|
|
|
namespace AxCopilot.Handlers;
|
|
|
|
public class RecentFilesHandler : IActionHandler
|
|
{
|
|
private static readonly string RecentFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Microsoft\\Windows\\Recent");
|
|
|
|
private static (DateTime At, List<(string Name, string LinkPath, DateTime Modified)> Files)? _cache;
|
|
|
|
private static readonly TimeSpan CacheTtl = TimeSpan.FromSeconds(10.0);
|
|
|
|
public string? Prefix => "recent";
|
|
|
|
public PluginMetadata Metadata => new PluginMetadata("RecentFiles", "최근 파일 — recent 뒤에 검색어 입력", "1.0", "AX");
|
|
|
|
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
|
{
|
|
string q = query.Trim();
|
|
if (string.IsNullOrWhiteSpace(q))
|
|
{
|
|
}
|
|
List<(string, string, DateTime)> recentFiles = GetRecentFiles();
|
|
IEnumerable<(string, string, DateTime)> source = recentFiles;
|
|
if (!string.IsNullOrWhiteSpace(q))
|
|
{
|
|
source = recentFiles.Where<(string, string, DateTime)>(((string Name, string LinkPath, DateTime Modified) f) => f.Name.Contains(q, StringComparison.OrdinalIgnoreCase));
|
|
}
|
|
List<LauncherItem> list = (from f in source.Take(20)
|
|
select new LauncherItem(f.Name, $"{f.Modified:yyyy-MM-dd HH:mm} · Enter로 열기", null, f.LinkPath, null, GetSymbol(f.Name))).ToList();
|
|
if (!list.Any())
|
|
{
|
|
list.Add(new LauncherItem(string.IsNullOrWhiteSpace(q) ? "최근 파일 없음" : "검색 결과 없음", string.IsNullOrWhiteSpace(q) ? "Windows Recent 폴더가 비어 있습니다" : ("'" + q + "' 파일을 최근 목록에서 찾을 수 없습니다"), null, null, null, "\ue946"));
|
|
}
|
|
return Task.FromResult((IEnumerable<LauncherItem>)list);
|
|
}
|
|
|
|
public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
|
{
|
|
if (item.Data is string text && File.Exists(text))
|
|
{
|
|
try
|
|
{
|
|
Process.Start(new ProcessStartInfo(text)
|
|
{
|
|
UseShellExecute = true
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn("최근 파일 열기 실패: " + ex.Message);
|
|
}
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private static List<(string Name, string LinkPath, DateTime Modified)> GetRecentFiles()
|
|
{
|
|
if (_cache.HasValue && DateTime.Now - _cache.Value.At < CacheTtl)
|
|
{
|
|
return _cache.Value.Files;
|
|
}
|
|
List<(string, string, DateTime)> list = new List<(string, string, DateTime)>();
|
|
try
|
|
{
|
|
if (!Directory.Exists(RecentFolder))
|
|
{
|
|
return list;
|
|
}
|
|
List<(string, FileInfo)> list2 = (from p in Directory.GetFiles(RecentFolder, "*.lnk")
|
|
select (Path: p, Info: new FileInfo(p)) into f
|
|
orderby f.Info.LastWriteTime descending
|
|
select f).Take(100).ToList();
|
|
foreach (var item3 in list2)
|
|
{
|
|
string item = item3.Item1;
|
|
FileInfo item2 = item3.Item2;
|
|
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item2.Name);
|
|
list.Add((fileNameWithoutExtension, item, item2.LastWriteTime));
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn("최근 파일 목록 읽기 실패: " + ex.Message);
|
|
}
|
|
_cache = (DateTime.Now, list);
|
|
return list;
|
|
}
|
|
|
|
private static string GetSymbol(string name)
|
|
{
|
|
string text = Path.GetExtension(name).ToLowerInvariant();
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
string result;
|
|
switch (text)
|
|
{
|
|
case ".exe":
|
|
case ".msi":
|
|
result = "\uecaa";
|
|
break;
|
|
case ".xlsx":
|
|
case ".xls":
|
|
case ".csv":
|
|
result = "\ue8a5";
|
|
break;
|
|
case ".docx":
|
|
case ".doc":
|
|
result = "\ue8a5";
|
|
break;
|
|
case ".pptx":
|
|
case ".ppt":
|
|
result = "\ue8a5";
|
|
break;
|
|
case ".pdf":
|
|
result = "\ue8a5";
|
|
break;
|
|
case ".txt":
|
|
case ".md":
|
|
case ".log":
|
|
result = "\ue8d2";
|
|
break;
|
|
case ".jpg":
|
|
case ".jpeg":
|
|
case ".png":
|
|
case ".gif":
|
|
case ".webp":
|
|
case ".bmp":
|
|
result = "\ueb9f";
|
|
break;
|
|
default:
|
|
result = "\ue8a5";
|
|
break;
|
|
}
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
return result;
|
|
}
|
|
}
|