using Avalonia.Threading; using MES.Utility.Core; using Microsoft.VisualBasic; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Text; using System.Threading; using Ursa.Controls; using 常用工具集.Base; using 常用工具集.Utility.Network; namespace 常用工具集.ViewModel._02网络相关 { public class FTP客户端ViewModel : ViewModelBase { public List EncodingList { get; set; } = new List() { Encoding.UTF8 }; public List StrEncodingList { get; set; } = new List() { "UTF-8" }; public int EncodingIndex { get; set; } = 0; private object _lock = new object(); private List msgList = new List(); public string Message { get { lock (_lock) { return msgList.GetStrArray("\r\n"); } } set { lock (_lock) { msgList.Add(value); } NotifyPropertyChanged(); } } public string IpAddress { get; set; } = "127.0.0.1"; public string UserName { get; set; } = "admin"; public string Password { get; set; } = "123456"; public int Port { get; set; } = 21; public bool IsAnonymous { get; set; } = false; public bool EnableFlag1 { get; set; } = true; public bool EnableFlag2 { get; set; } = false; private FtpHelper ftp; public DelegateCommand ConnectCmd { get; set; } public DelegateCommand DisconnectCmd { get; set; } public DelegateCommand LocalDoubleClickCommand { get; set; } public DelegateCommand LocalHomeClickCommand { get; set; } public DelegateCommand RemoteHomeClickCommand { get; set; } public DelegateCommand RemoteDoubleClickCommand { get; set; } public DelegateCommand DownloadClickCommand { get; set; } public DelegateCommand UploadClickCommand { get; set; } public DelegateCommand RemoteRenameClickCommand { get; set; } public DelegateCommand RemoteDeleteClickCommand { get; set; } public string LocalPath1 { get; set; } = "本地"; public string CurrentLocalPath { get; set; } = ""; public ObservableCollection LocalTree { get; set; } public MyDir LocalTreeSelectedItem { get; set; } = null; public string RemotePath1 { get; set; } = "远程"; public string CurrentRemotePath { get; set; } = ""; public ObservableCollection RemoteTree { get; set; } public MyDir RemoteTreeSelectedItem { get; set; } = null; public FTP客户端ViewModel() { LocalTree = GetFoldersAndFiles(); ConnectCmd = new DelegateCommand(ConnectCmdFunc); DisconnectCmd = new DelegateCommand(DisconnectCmdFunc); RemoteHomeClickCommand = new DelegateCommand(RemoteHomeClickCommandFunc); LocalHomeClickCommand = new DelegateCommand(LocalHomeClickCommandFunc); LocalDoubleClickCommand = new DelegateCommand(LocalDoubleClickCommandFunc); RemoteDoubleClickCommand = new DelegateCommand(RemoteDoubleClickCommandFunc); DownloadClickCommand = new DelegateCommand(DownloadClickCommandFunc); UploadClickCommand = new DelegateCommand(UploadClickCommandFunc); RemoteDeleteClickCommand = new DelegateCommand(RemoteDeleteClickCommandFunc); RemoteRenameClickCommand = new DelegateCommand(RemoteRenameClickCommandFunc); } private void ConnectCmdFunc(object obj) { if (IsAnonymous) { try { ftp = new FtpHelper(IpAddress, Port, EncodingList[EncodingIndex]); RemoteTree = GetRemoteFoldersAndFiles(); } catch { GlobalValues.Error("FTP连接失败"); return; } } else { try { ftp = new FtpHelper(IpAddress, Port, UserName, Password, EncodingList[EncodingIndex]); RemoteTree = GetRemoteFoldersAndFiles(); } catch { GlobalValues.Error("FTP连接失败"); return; } } EnableFlag1 = false; EnableFlag2 = true; } private void DisconnectCmdFunc(object obj) { ftp = null; RemoteTree = new ObservableCollection(); RemotePath1 = "远程"; CurrentRemotePath = ""; EnableFlag1 = true; EnableFlag2 = false; } private void RemoteDoubleClickCommandFunc(object obj) { try { MyDir current = (MyDir)obj; if (current == null) return; if (current.IsBack) { string path = CurrentRemotePath; if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1); int index = path.LastIndexOf("/"); if (index == -1) { path = ""; } else { path = path.Substring(0, index + 1); } if (path == "") { CurrentRemotePath = ""; RemotePath1 = "远程"; } else { CurrentRemotePath = path; RemotePath1 = "远程:" + CurrentRemotePath; } RemoteTree = GetRemoteFoldersAndFiles(); return; } //文件不能双击 if (!current.IsDirectory) { return; } CurrentRemotePath = current.Path; RemotePath1 = "远程:" + CurrentRemotePath; RemoteTree = GetRemoteFoldersAndFiles(); } catch (Exception ex) { GlobalValues.Error("FTP连接失败"); DisconnectCmdFunc(null); } } private void LocalDoubleClickCommandFunc(object obj) { MyDir current = (MyDir)obj; if (current == null) return; if (current.IsBack) { string path = CurrentLocalPath; if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1); int index = path.LastIndexOf("/"); if (index == -1) { path = ""; } else { path = path.Substring(0, index + 1); } if (path == "") { CurrentLocalPath = ""; LocalPath1 = "本地"; } else { CurrentLocalPath = path.Replace("\\", "/"); LocalPath1 = "本地:" + CurrentLocalPath; } LocalTree = GetFoldersAndFiles(); return; } //文件不能双击 if (!current.IsDirectory) { return; } CurrentLocalPath = current.Path; LocalPath1 = "本地:" + CurrentLocalPath; LocalTree = GetFoldersAndFiles(); } private ObservableCollection GetRemoteFoldersAndFiles() { ObservableCollection list = new ObservableCollection(); List list2 = ftp.GetList(CurrentRemotePath).OrderByDescending(it => it.IsDirectory).ToList(); if (CurrentRemotePath != "") { list.Add(new MyDir { Name = $"...", Path = $"", IsDirectory = true, IsBack = true, }); } foreach (var ftpFileInfo in list2) { if (ftpFileInfo.IsDirectory) { list.Add(new MyDir { Name = $"{ftpFileInfo.Name}", Path = $"{CurrentRemotePath}{ftpFileInfo.Name}/", IsDirectory = true }); } else { list.Add(new MyDir { Name = $"{ftpFileInfo.Name}", Path = $"{CurrentRemotePath}{ftpFileInfo.Name}", IsDirectory = false }); } } return list; } private ObservableCollection GetFoldersAndFiles() { ObservableCollection list = new ObservableCollection(); if (CurrentLocalPath == "") { list.Add(new MyDir { Name = "桌面", Path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory).Replace("\\", "/"), IsDirectory = true }); // 获取所有盘符 DriveInfo[] allDrives = DriveInfo.GetDrives(); // 过滤出固态硬盘(SSD)和机械硬盘(HDD) List systemDrives = allDrives.Where(drive => drive.IsReady) // 确保驱动器已准备好访问 .Where(drive => drive.DriveType == DriveType.Fixed) // 仅固定类型的驱动器 .Select(drive => drive.Name.Substring(0, 1)) // 获取盘符 .ToList(); // 输出系统盘符 foreach (var drive in systemDrives) { list.Add(new MyDir { Name = $"{drive}", Path = $"{drive}:/", IsDirectory = true }); } } else { list.Add(new MyDir { Name = "...", Path = "", IsDirectory = true, IsBack = true, }); List dirList = Directory.GetDirectories(CurrentLocalPath).Select(it => it.Replace("\\", "/")).ToList(); foreach (string dirPath in dirList) { list.Add(new MyDir { Name = System.IO.Path.GetFileName(dirPath), Path = dirPath + "/", IsDirectory = true, }); } List fileList = Directory.GetFiles(CurrentLocalPath).Select(it => it.Replace("\\", "/")).ToList(); foreach (string filePath in fileList) { list.Add(new MyDir { Name = System.IO.Path.GetFileName(filePath), Path = filePath, IsDirectory = false, }); } } return list; } private void LocalHomeClickCommandFunc(object obj) { CurrentLocalPath = ""; LocalPath1 = "本地"; LocalTree = GetFoldersAndFiles(); } private void RemoteHomeClickCommandFunc(object obj) { try { CurrentRemotePath = ""; RemotePath1 = "远程"; RemoteTree = GetRemoteFoldersAndFiles(); } catch (Exception ex) { GlobalValues.Error("FTP连接失败"); DisconnectCmdFunc(null); } } /// /// 上传文件 /// /// private async void UploadClickCommandFunc(object obj) { if (LocalTreeSelectedItem == null) { await MessageBox.ShowAsync("请选择要上传的文件或文件夹"); return; } if (LocalTreeSelectedItem.IsBack) { return; } bool cover = false; var result = await MessageBox.ShowOverlayAsync("上传过程中可能文件存在,是否覆盖上传", "提示", button: MessageBoxButton.YesNo); if (result != MessageBoxResult.Yes) { cover = false; } else { cover = true; } //上传文件夹 if (LocalTreeSelectedItem.IsDirectory) { new Thread(() => { UploadDir(LocalTreeSelectedItem, CurrentRemotePath, cover); Message = $"文件夹上传完成:{LocalTreeSelectedItem.Name}"; Dispatcher.UIThread.Invoke(() => { RemoteTree = GetRemoteFoldersAndFiles(); }); }).Start(); } //上传文件 else { new Thread(() => { try { //判断远端是否存在文件,是否覆盖 bool isExist = ftp.IsFileExist(CurrentRemotePath, LocalTreeSelectedItem.Name); if (isExist && !cover) { return; } Message = $"准备上传:{LocalTreeSelectedItem.Path}"; ftp.UploadFile(LocalTreeSelectedItem.Path, CurrentRemotePath + LocalTreeSelectedItem.Name); Message = $"上传完成:{LocalTreeSelectedItem.Path}"; } catch (Exception ex) { Message = $"上传失败:{LocalTreeSelectedItem.Path}"; } Dispatcher.UIThread.Invoke(() => { RemoteTree = GetRemoteFoldersAndFiles(); }); }).Start(); } } /// /// 下载文件 /// /// private async void DownloadClickCommandFunc(object obj) { if (RemoteTreeSelectedItem == null) { await MessageBox.ShowAsync("请选择要下载的文件或文件夹"); return; } if (CurrentLocalPath == "") { await MessageBox.ShowAsync("请选择本地路径"); return; } if (RemoteTreeSelectedItem.IsBack) { return; } bool cover = false; var result = await MessageBox.ShowOverlayAsync("下载过程中可能文件存在,是否覆盖下载", "提示", button: MessageBoxButton.YesNo); if (result != MessageBoxResult.Yes) { cover = false; } else { cover = true; } //下载文件夹 if (RemoteTreeSelectedItem.IsDirectory) { new Thread(() => { DownloadDir(RemoteTreeSelectedItem, CurrentLocalPath, cover); Message = $"文件夹下载完成:{RemoteTreeSelectedItem.Name}"; Dispatcher.UIThread.Invoke(() => { LocalTree = GetFoldersAndFiles(); }); }).Start(); } //下载文件 else { new Thread(() => { try { if (File.Exists(CurrentLocalPath + "/" + RemoteTreeSelectedItem.Name) && !cover) { return; } Message = $"准备下载:{RemoteTreeSelectedItem.Name}"; ftp.DownloadFile(RemoteTreeSelectedItem.Path, CurrentLocalPath + "/" + RemoteTreeSelectedItem.Name); Message = $"下载完成:{RemoteTreeSelectedItem.Name}"; } catch (Exception ex) { Message = $"下载失败:{ex.Message}"; } Dispatcher.UIThread.Invoke(() => { LocalTree = GetFoldersAndFiles(); }); }).Start(); } } /// /// 删除FTP文件 /// /// /// private async void RemoteDeleteClickCommandFunc(object obj) { try { if (RemoteTreeSelectedItem == null) { await MessageBox.ShowAsync("请选择要删除的文件或文件夹"); return; } if (RemoteTreeSelectedItem.IsBack) { return; } var result = await MessageBox.ShowOverlayAsync("是否确定删除", "提示", button: MessageBoxButton.YesNo); if (result != MessageBoxResult.Yes) { return; } if (RemoteTreeSelectedItem.IsDirectory) { new Thread(() => { try { DeleteDirecory(RemoteTreeSelectedItem.Path); Message = $"删除成功:{RemoteTreeSelectedItem.Path}"; } catch (Exception ex) { Message = $"删除失败:{ex.Message}"; } Dispatcher.UIThread.Invoke(() => { RemoteTree = GetRemoteFoldersAndFiles(); }); }).Start(); } else { new Thread(() => { Message = $"准备删除:{RemoteTreeSelectedItem.Path}"; try { ftp.DeleteFile(RemoteTreeSelectedItem.Path); Message = $"删除成功:{RemoteTreeSelectedItem.Path}"; } catch (Exception ex) { Message = $"删除失败:{ex.Message}"; } Dispatcher.UIThread.Invoke(() => { RemoteTree = GetRemoteFoldersAndFiles(); }); }).Start(); } } catch (Exception ex) { await MessageBox.ShowAsync(ex.Message); } } private void DeleteDirecory(string path) { List list = ftp.GetList(path); foreach (FtpFileInfo info in list) { if (info.IsDirectory) { DeleteDirecory(path + info.Name + "/"); } else { Message = $"准备删除:{path + info.Name}"; try { ftp.DeleteFile(path + info.Name); Message = $"删除成功:{path + info.Name}"; } catch (Exception ex) { Message = $"删除失败:{ex.Message}"; } } } ftp.DeleteDirectory(path); } /// /// 递归调用 /// /// /// /// private void DownloadDir(MyDir remoteTreeSelectedItem, string currentLocalPath, bool cover) { //文件夹是否存在 string localPath = currentLocalPath + "/" + remoteTreeSelectedItem.Name; if (!Directory.Exists(localPath)) { Directory.CreateDirectory(localPath); } List myDirs = ftp.GetList(remoteTreeSelectedItem.Path); foreach (FtpFileInfo f in myDirs) { if (f.IsDirectory) { MyDir dir = new MyDir { IsDirectory = true, Name = f.Name, Path = remoteTreeSelectedItem.Path + f.Name + "/" }; DownloadDir(dir, localPath, cover); } else { try { if (File.Exists(localPath + "/" + f.Name) && !cover) { return; } Message = $"准备下载:{remoteTreeSelectedItem.Path + f.Name}"; ftp.DownloadFile(remoteTreeSelectedItem.Path + f.Name, localPath + "/" + f.Name); Message = $"下载完成:{remoteTreeSelectedItem.Path + f.Name}"; } catch (Exception ex) { Message = $"下载失败:{ex.Message}"; } } } } private void UploadDir(MyDir localTreeSelectedItem, string currentRemotePath, bool cover) { //文件夹是否存在 string remotePath = currentRemotePath + localTreeSelectedItem.Name + "/"; if (!ftp.FolderExists(currentRemotePath, localTreeSelectedItem.Name)) { ftp.CreateFolder(remotePath); } string[] dirList = Directory.GetDirectories(localTreeSelectedItem.Path).Select(it => it.Replace("\\", "/")).ToArray(); string[] fileList = Directory.GetFiles(localTreeSelectedItem.Path).Select(it => it.Replace("\\", "/")).ToArray(); foreach (string f in dirList) { MyDir dir = new MyDir { IsDirectory = true, Name = System.IO.Path.GetFileName(f), Path = f }; UploadDir(dir, remotePath, cover); } foreach (string f in fileList) { try { bool isExist = ftp.IsFileExist(remotePath + "/", System.IO.Path.GetFileName(f)); if (isExist) { continue; } Message = $"准备上传:{localTreeSelectedItem.Path + System.IO.Path.GetFileName(f)}"; ftp.UploadFile(localTreeSelectedItem.Path + "/" + System.IO.Path.GetFileName(f), remotePath + "/" + System.IO.Path.GetFileName(f)); Message = $"上传完成:{localTreeSelectedItem.Path + System.IO.Path.GetFileName(f)}"; } catch (Exception ex) { Message = $"上传失败:{ex.Message}"; } } } private void RemoteRenameClickCommandFunc(object obj) { if (RemoteTreeSelectedItem == null) { MessageBox.ShowAsync("请选择要重命名的文件或文件夹"); return; } if (RemoteTreeSelectedItem.IsBack) { return; } string newName = Interaction.InputBox("请输入新名字", "", "", 200, 100); if (newName.IsNullOrEmpty()) { MessageBox.ShowAsync("请输入新文件名"); return; } string path = ""; if (RemoteTreeSelectedItem.IsDirectory) { path = CurrentRemotePath; if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1); int index = path.LastIndexOf("/"); if (index == -1) { path = ""; } else { path = path.Substring(0, index + 1); } path += newName + "/"; } else { path = CurrentRemotePath; if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1); int index = path.LastIndexOf("/"); if (index == -1) { path = ""; } else { path = path.Substring(0, index + 1); } string ext = System.IO.Path.GetExtension(RemoteTreeSelectedItem.Path); if (!newName.ToLower().EndsWith(ext.ToLower())) { path = path + newName + ext; } } new Thread(() => { try { ftp.Rename(RemoteTreeSelectedItem.Path, path); Dispatcher.UIThread.Invoke(() => { RemoteTree = GetRemoteFoldersAndFiles(); }); } catch (Exception ex) { Message = $"重命名失败:{ex.Message}"; } }).Start(); } } public class MyDir { public string Path { get; set; } public string Name { get; set; } public bool IsDirectory { get; set; } public bool IsBack { get; set; } } }