Files
DevToolsAvalonia/常用工具集/ViewModels/02网络相关/FTP服务ViewModel.cs
2025-08-26 08:37:44 +08:00

160 lines
5.7 KiB
C#

using Avalonia.Platform.Storage;
using FubarDev.FtpServer;
using FubarDev.FtpServer.AccountManagement;
using FubarDev.FtpServer.FileSystem.DotNet;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Ursa.Controls;
using .Base;
namespace .ViewModel._02网络相关
{
public class FTP服务ViewModel : ViewModelBase
{
public bool Enabled1 { get; set; } = true;
public string ButtonName { get; set; } = "开启服务";
public string Path { get; set; } = "d:/";
public int Port { get; set; } = 21;
public string UserName { get; set; } = "admin";
public string Password { get; set; } = "123456";
public bool Anonymous { get; set; } = true;
public int MaxConnectCount { get; set; } = 100;
public DelegateCommand SelectPathCmd { get; set; }
public DelegateCommand StartCmd { get; set; }
public FTP服务ViewModel()
{
SelectPathCmd = new DelegateCommand(SelectPathCmdFunc);
StartCmd = new DelegateCommand(StartCmdFunc);
}
private void StartCmdFunc(object obj)
{
if (ButtonName == "开启服务")
{
bool flag = Start(UserName, Password, Path, Port, Anonymous, MaxConnectCount);
if (!flag)
{
return;
}
Enabled1 = false;
ButtonName = "停止服务";
}
else
{
bool flag = Stop();
if (!flag)
return;
Enabled1 = true;
ButtonName = "开启服务";
}
}
private async void SelectPathCmdFunc(object obj)
{
var sp = GlobalValues.StorageProvider;
if (sp is null) return;
var result = await sp.OpenFolderPickerAsync(new FolderPickerOpenOptions()
{
Title = "选择FTP主目录",
AllowMultiple = false,
});
if (result == null || result.Count == 0)
{
await MessageBox.ShowAsync("文件夹路径不能为空");
return;
}
Path = result.FirstOrDefault()?.Path.LocalPath;
}
internal static string UserName1 { get; set; }
internal static string Password1 { get; set; }
public ServiceProvider serviceProvider;
public IFtpServerHost ftpServerHost;
private bool Start(string userName, string password, string path, int port, bool anonymous, int maxConnectCount)
{
try
{
UserName1 = userName;
Password1 = password;
// 设置依赖项注入
var services = new ServiceCollection();
// 使用%TEMP%/TestFtpServer作为根文件夹
services.Configure<DotNetFileSystemOptions>(opt =>
{
opt.RootPath = path;
});
services.Configure<FtpConnectionOptions>(opt => opt.DefaultEncoding = Encoding.GetEncoding("GB2312"));
// 添加FTP服务器服务
// DotNetFileSystemProvider = 使用.NET文件系统功能
// AnonymousMembershipProvider = 仅允许匿名登录
services.AddFtpServer(builder =>
{
builder.UseDotNetFileSystem(); // 使用.NET文件系统功能
if (anonymous)
{
builder.EnableAnonymousAuthentication();// 允许匿名登录
}
builder.Services.AddSingleton<IMembershipProvider, TestMembershipProvider>();//用户登录
});
// 配置FTP服务器
services.Configure<FtpServerOptions>(opt =>
{
opt.ServerAddress = "*";
opt.Port = port;
opt.MaxActiveConnections = maxConnectCount;
});
serviceProvider = services.BuildServiceProvider();
ftpServerHost = serviceProvider.GetRequiredService<IFtpServerHost>();
ftpServerHost.StartAsync(CancellationToken.None);
return true;
}
catch (Exception ex)
{
return false;
}
}
public class TestMembershipProvider : IMembershipProvider
{
public Task<MemberValidationResult> ValidateUserAsync(string name, string password)
{
if (UserName1 == name && password == Password1)
{
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim(ClaimTypes.Name, name));
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
return Task.FromResult(new MemberValidationResult(MemberValidationStatus.AuthenticatedUser, new ClaimsPrincipal(identity)));
}
return Task.FromResult(new MemberValidationResult(MemberValidationStatus.InvalidLogin));
}
}
private bool Stop()
{
try
{
// 停止FTP服务器
ftpServerHost.StopAsync(CancellationToken.None).Wait();
serviceProvider.Dispose();
ftpServerHost = null;
serviceProvider = null;
return true;
}
catch (Exception ex)
{
return false;
}
}
}
}