mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-03-19 08:19:48 +08:00
182 lines
5.5 KiB
C#
182 lines
5.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace BetterGenshinImpact.Core.Script.WebView;
|
|
|
|
public class FileSystemItem
|
|
{
|
|
public string Name { get; set; }
|
|
public string RelativePath { get; set; }
|
|
public bool IsDirectory { get; set; }
|
|
public long Size { get; set; }
|
|
public DateTime LastModified { get; set; }
|
|
}
|
|
|
|
[ClassInterface(ClassInterfaceType.AutoDual)]
|
|
[ComVisible(true)]
|
|
public class FileAccessBridge
|
|
{
|
|
private readonly string _allowedDirectory;
|
|
private readonly string _normalizedAllowedPath;
|
|
|
|
public FileAccessBridge(string allowedDirectory)
|
|
{
|
|
if (string.IsNullOrEmpty(allowedDirectory))
|
|
{
|
|
throw new ArgumentException("允许访问的目录不能为空", nameof(allowedDirectory));
|
|
}
|
|
|
|
if (!Directory.Exists(allowedDirectory))
|
|
{
|
|
throw new ArgumentException("目录不存在", nameof(allowedDirectory));
|
|
}
|
|
|
|
_allowedDirectory = Path.GetFullPath(allowedDirectory);
|
|
_normalizedAllowedPath = _allowedDirectory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
|
}
|
|
|
|
private bool IsPathAllowed(string path)
|
|
{
|
|
try
|
|
{
|
|
var fullPath = Path.GetFullPath(path);
|
|
var normalizedPath = fullPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
|
return normalizedPath.StartsWith(_normalizedAllowedPath, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public string ReadFile(string relativePath)
|
|
{
|
|
try
|
|
{
|
|
var fullPath = Path.Combine(_allowedDirectory, relativePath);
|
|
if (!IsPathAllowed(fullPath))
|
|
throw new UnauthorizedAccessException($"访问路径 '{relativePath}' 被拒绝");
|
|
|
|
if (!File.Exists(fullPath))
|
|
throw new FileNotFoundException($"文件 '{relativePath}' 不存在");
|
|
|
|
return File.ReadAllText(fullPath, Encoding.UTF8);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception($"读取文件失败: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public void WriteFile(string relativePath, string content)
|
|
{
|
|
try
|
|
{
|
|
var fullPath = Path.Combine(_allowedDirectory, relativePath);
|
|
if (!IsPathAllowed(fullPath))
|
|
throw new UnauthorizedAccessException($"访问路径 '{relativePath}' 被拒绝");
|
|
|
|
// var directory = Path.GetDirectoryName(fullPath);
|
|
// if (!string.IsNullOrEmpty(directory))
|
|
// Directory.CreateDirectory(directory);
|
|
|
|
File.WriteAllText(fullPath, content, Encoding.UTF8);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception($"写入文件失败: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public bool FileExists(string relativePath)
|
|
{
|
|
try
|
|
{
|
|
var fullPath = Path.Combine(_allowedDirectory, relativePath);
|
|
if (!IsPathAllowed(fullPath))
|
|
return false;
|
|
|
|
return File.Exists(fullPath);
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool DirectoryExists(string relativePath)
|
|
{
|
|
try
|
|
{
|
|
var fullPath = Path.Combine(_allowedDirectory, relativePath);
|
|
if (!IsPathAllowed(fullPath))
|
|
return false;
|
|
|
|
return Directory.Exists(fullPath);
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public string ListItems(string relativePath = "")
|
|
{
|
|
try
|
|
{
|
|
var fullPath = string.IsNullOrEmpty(relativePath)
|
|
? _allowedDirectory
|
|
: Path.Combine(_allowedDirectory, relativePath);
|
|
|
|
if (!IsPathAllowed(fullPath))
|
|
throw new UnauthorizedAccessException($"访问路径 '{relativePath}' 被拒绝");
|
|
|
|
if (!Directory.Exists(fullPath))
|
|
return JsonConvert.SerializeObject(new List<FileSystemItem>());
|
|
|
|
var items = new List<FileSystemItem>();
|
|
|
|
// 添加目录
|
|
var directories = Directory.GetDirectories(fullPath);
|
|
foreach (var directory in directories)
|
|
{
|
|
var relativeName = Path.GetRelativePath(_allowedDirectory, directory);
|
|
var dirInfo = new DirectoryInfo(directory);
|
|
items.Add(new FileSystemItem
|
|
{
|
|
Name = Path.GetFileName(directory),
|
|
RelativePath = relativeName,
|
|
IsDirectory = true,
|
|
Size = 0,
|
|
LastModified = dirInfo.LastWriteTime
|
|
});
|
|
}
|
|
|
|
// 添加文件
|
|
var files = Directory.GetFiles(fullPath);
|
|
foreach (var file in files)
|
|
{
|
|
var relativeName = Path.GetRelativePath(_allowedDirectory, file);
|
|
var fileInfo = new FileInfo(file);
|
|
items.Add(new FileSystemItem
|
|
{
|
|
Name = Path.GetFileName(file),
|
|
RelativePath = relativeName,
|
|
IsDirectory = false,
|
|
Size = fileInfo.Length,
|
|
LastModified = fileInfo.LastWriteTime
|
|
});
|
|
}
|
|
|
|
return JsonConvert.SerializeObject(items);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception($"列出项目失败: {ex.Message}");
|
|
}
|
|
}
|
|
} |