初始化上传
This commit is contained in:
766
常用工具集/ViewModels/02网络相关/FTP客户端ViewModel.cs
Normal file
766
常用工具集/ViewModels/02网络相关/FTP客户端ViewModel.cs
Normal file
@@ -0,0 +1,766 @@
|
||||
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<Encoding> EncodingList { get; set; } = new List<Encoding>() { Encoding.UTF8 };
|
||||
|
||||
public List<string> StrEncodingList { get; set; } = new List<string>() { "UTF-8" };
|
||||
|
||||
public int EncodingIndex { get; set; } = 0;
|
||||
|
||||
private object _lock = new object();
|
||||
private List<string> msgList = new List<string>();
|
||||
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<MyDir> LocalTree { get; set; }
|
||||
public MyDir LocalTreeSelectedItem { get; set; } = null;
|
||||
|
||||
|
||||
|
||||
public string RemotePath1 { get; set; } = "远程";
|
||||
public string CurrentRemotePath { get; set; } = "";
|
||||
public ObservableCollection<MyDir> 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<MyDir>();
|
||||
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<MyDir> GetRemoteFoldersAndFiles()
|
||||
{
|
||||
ObservableCollection<MyDir> list = new ObservableCollection<MyDir>();
|
||||
List<FtpFileInfo> 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<MyDir> GetFoldersAndFiles()
|
||||
{
|
||||
ObservableCollection<MyDir> list = new ObservableCollection<MyDir>();
|
||||
if (CurrentLocalPath == "")
|
||||
{
|
||||
list.Add(new MyDir
|
||||
{
|
||||
Name = "桌面",
|
||||
Path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory).Replace("\\", "/"),
|
||||
IsDirectory = true
|
||||
});
|
||||
// 获取所有盘符
|
||||
DriveInfo[] allDrives = DriveInfo.GetDrives();
|
||||
// 过滤出固态硬盘(SSD)和机械硬盘(HDD)
|
||||
List<string> 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<string> 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<string> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上传文件
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载文件
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除FTP文件
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
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<FtpFileInfo> 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);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 递归调用
|
||||
/// </summary>
|
||||
/// <param name="remoteTreeSelectedItem"></param>
|
||||
/// <param name="currentLocalPath"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void DownloadDir(MyDir remoteTreeSelectedItem, string currentLocalPath, bool cover)
|
||||
{
|
||||
//文件夹是否存在
|
||||
string localPath = currentLocalPath + "/" + remoteTreeSelectedItem.Name;
|
||||
if (!Directory.Exists(localPath))
|
||||
{
|
||||
Directory.CreateDirectory(localPath);
|
||||
}
|
||||
List<FtpFileInfo> 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; }
|
||||
}
|
||||
}
|
||||
159
常用工具集/ViewModels/02网络相关/FTP服务ViewModel.cs
Normal file
159
常用工具集/ViewModels/02网络相关/FTP服务ViewModel.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
271
常用工具集/ViewModels/02网络相关/HTTP调试ViewModel.cs
Normal file
271
常用工具集/ViewModels/02网络相关/HTTP调试ViewModel.cs
Normal file
@@ -0,0 +1,271 @@
|
||||
using MES.Utility.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using 常用工具集.Base;
|
||||
using System.Threading;
|
||||
using 常用工具集.Utility.Network;
|
||||
using System.IO;
|
||||
using Ursa.Controls;
|
||||
using Avalonia.Threading;
|
||||
using Avalonia.Platform.Storage;
|
||||
|
||||
namespace 常用工具集.ViewModel._02网络相关
|
||||
{
|
||||
public class HTTP调试ViewModel : ViewModelBase
|
||||
{
|
||||
private bool getChecked = true;
|
||||
public bool GetChecked
|
||||
{
|
||||
get { return getChecked; }
|
||||
set
|
||||
{
|
||||
getChecked = value;
|
||||
if (value)
|
||||
{
|
||||
Visiable =false;
|
||||
}
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
private bool downloadChecked = false;
|
||||
public bool DownloadChecked
|
||||
{
|
||||
get { return downloadChecked; }
|
||||
set
|
||||
{
|
||||
downloadChecked = value;
|
||||
if (value)
|
||||
{
|
||||
Visiable = false;
|
||||
}
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
private bool postChecked = false;
|
||||
public bool PostChecked
|
||||
{
|
||||
get { return postChecked; }
|
||||
set
|
||||
{
|
||||
postChecked = value;
|
||||
if (value)
|
||||
{
|
||||
Visiable = true;
|
||||
}
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Url { get; set; } = "";
|
||||
|
||||
public DelegateCommand ButtonCmd { get; set; }
|
||||
|
||||
public bool JsonChecked { get; set; } = true;
|
||||
public bool FormChecked { get; set; } = false;
|
||||
|
||||
public int Timeout { get; set; } = 1000;
|
||||
|
||||
public bool Visiable { get; set; } = false;
|
||||
|
||||
public string Parms { get; set; } = "";
|
||||
public string Result { get; set; } = "";
|
||||
public bool ButtonEnabled { get; set; } = true;
|
||||
public HTTP调试ViewModel()
|
||||
{
|
||||
ButtonCmd = new DelegateCommand(ButtonCmdFunc);
|
||||
}
|
||||
|
||||
private void ButtonCmdFunc(object obj)
|
||||
{
|
||||
if (Url.IsNullOrEmpty())
|
||||
{
|
||||
MessageBox.ShowAsync("请输入URL");
|
||||
return;
|
||||
}
|
||||
string url = Url;
|
||||
if (!url.ToLower().StartsWith("http"))
|
||||
{
|
||||
url = "http://" + url;
|
||||
}
|
||||
int timeout = Timeout;
|
||||
if (GetChecked)
|
||||
{
|
||||
Dictionary<string, string> dict = new Dictionary<string, string>();
|
||||
if (url.Contains("?"))
|
||||
{
|
||||
int index = url.IndexOf("?");
|
||||
string parms = url.Substring(index + 1, url.Length - index - 1);
|
||||
string[] parmsArray = parms.Split('&');
|
||||
foreach (string parm in parmsArray)
|
||||
{
|
||||
if (parm.Contains("="))
|
||||
{
|
||||
string[] array = parm.Split('=');
|
||||
dict.Add(array[0], array[1]);
|
||||
}
|
||||
}
|
||||
parmsArray = Parms.Split('&');
|
||||
foreach (string parm in parmsArray)
|
||||
{
|
||||
if (parm.Contains("="))
|
||||
{
|
||||
string[] array = parm.Split('=');
|
||||
dict.Add(array[0], array[1]);
|
||||
}
|
||||
}
|
||||
url = url.Substring(0, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] parmsArray = Parms.Split('&');
|
||||
foreach (string parm in parmsArray)
|
||||
{
|
||||
if (parm.Contains("="))
|
||||
{
|
||||
string[] array = parm.Split('=');
|
||||
dict.Add(array[0], array[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
ButtonEnabled = false;
|
||||
Result = string.Empty;
|
||||
new Thread(() =>
|
||||
{
|
||||
string ret = HttpUtils.DoGet(url, dict, timeout);
|
||||
if (!ret.IsNullOrEmpty())
|
||||
{
|
||||
Result = ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = "网络或服务器异常";
|
||||
}
|
||||
ButtonEnabled = true;
|
||||
}).Start();
|
||||
}
|
||||
else if (DownloadChecked)
|
||||
{
|
||||
Dictionary<string, string> dict = new Dictionary<string, string>();
|
||||
if (url.Contains("?"))
|
||||
{
|
||||
int index = url.IndexOf("?");
|
||||
string parms = url.Substring(index + 1, url.Length - index - 1);
|
||||
string[] parmsArray = parms.Split('&');
|
||||
foreach (string parm in parmsArray)
|
||||
{
|
||||
if (parm.Contains("="))
|
||||
{
|
||||
string[] array = parm.Split('=');
|
||||
dict.Add(array[0], array[1]);
|
||||
}
|
||||
}
|
||||
parmsArray = Parms.Split('&');
|
||||
foreach (string parm in parmsArray)
|
||||
{
|
||||
if (parm.Contains("="))
|
||||
{
|
||||
string[] array = parm.Split('=');
|
||||
dict.Add(array[0], array[1]);
|
||||
}
|
||||
}
|
||||
url = url.Substring(0, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] parmsArray = Parms.Split('&');
|
||||
foreach (string parm in parmsArray)
|
||||
{
|
||||
if (parm.Contains("="))
|
||||
{
|
||||
string[] array = parm.Split('=');
|
||||
dict.Add(array[0], array[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
ButtonEnabled = false;
|
||||
Result = string.Empty;
|
||||
new Thread(() =>
|
||||
{
|
||||
byte[] ret = HttpUtils.DoGetFile(url, timeout);
|
||||
if (ret == null)
|
||||
{
|
||||
Result = "网络或服务器异常";
|
||||
}
|
||||
else
|
||||
{
|
||||
Dispatcher.UIThread.Invoke(async () =>
|
||||
{
|
||||
var sp = GlobalValues.StorageProvider;
|
||||
if (sp is null) return;
|
||||
var result = await sp.SaveFilePickerAsync(new FilePickerSaveOptions()
|
||||
{
|
||||
Title = "保存文件"
|
||||
});
|
||||
if (result == null) return;
|
||||
string filePath = result.Path.LocalPath;
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
|
||||
{
|
||||
fs.Write(ret, 0, ret.Length);
|
||||
}
|
||||
await MessageBox.ShowAsync("下载完成");
|
||||
});
|
||||
}
|
||||
ButtonEnabled = true;
|
||||
}).Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
//JSON
|
||||
if (JsonChecked)
|
||||
{
|
||||
|
||||
ButtonEnabled = false;
|
||||
Result = string.Empty;
|
||||
new Thread(() =>
|
||||
{
|
||||
string ret = HttpUtils.DoPostJson(url, Parms, timeout);
|
||||
if (!ret.IsNullOrEmpty())
|
||||
{
|
||||
Result = ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = "网络或服务器异常";
|
||||
}
|
||||
ButtonEnabled = true;
|
||||
}).Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, string> dict = new Dictionary<string, string>();
|
||||
|
||||
string[] parmsArray = Parms.Split('&');
|
||||
foreach (string parm in parmsArray)
|
||||
{
|
||||
if (parm.Contains("="))
|
||||
{
|
||||
string[] array = parm.Split('=');
|
||||
dict.Add(array[0], array[1]);
|
||||
}
|
||||
}
|
||||
ButtonEnabled = false;
|
||||
Result = string.Empty;
|
||||
new Thread(() =>
|
||||
{
|
||||
string ret = HttpUtils.DoPostForm(url, dict, timeout);
|
||||
if (!ret.IsNullOrEmpty())
|
||||
{
|
||||
Result = ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = "网络或服务器异常";
|
||||
}
|
||||
ButtonEnabled = true;
|
||||
}).Start();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
200
常用工具集/ViewModels/02网络相关/端口占用扫描ViewModel.cs
Normal file
200
常用工具集/ViewModels/02网络相关/端口占用扫描ViewModel.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
using Avalonia.Threading;
|
||||
using MES.Utility.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using 常用工具集.Base;
|
||||
|
||||
namespace 常用工具集.ViewModel._02网络相关
|
||||
{
|
||||
public class 端口占用扫描ViewModel : ViewModelBase
|
||||
{
|
||||
public bool Enabled1 { get; set; } = true;
|
||||
public bool Enabled2 { get; set; } = false;
|
||||
|
||||
public int SelectedIndex { get; set; } = -1;
|
||||
|
||||
public ObservableCollection<ScanResult> DataList { get; set; } = new ObservableCollection<ScanResult>();
|
||||
|
||||
public int ProgressValue { get; set; } = 0;
|
||||
public int ProgressMax { get; set; } = 100;
|
||||
|
||||
public DelegateCommand StartScanCmd { get; set; }
|
||||
public DelegateCommand CloseProcessCmd { get; set; }
|
||||
|
||||
public 端口占用扫描ViewModel()
|
||||
{
|
||||
StartScanCmd = new DelegateCommand(StartScanCmdFunc);
|
||||
CloseProcessCmd = new DelegateCommand(CloseProcessCmdFunc);
|
||||
}
|
||||
|
||||
private void CloseProcessCmdFunc(object obj)
|
||||
{
|
||||
if (SelectedIndex < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int pid = DataList[SelectedIndex].PID;
|
||||
Process process = Process.GetProcessById(pid);
|
||||
if (process == null)
|
||||
{
|
||||
GlobalValues.Error("获取进程相关信息失败,请尝试重新操作");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
process.Kill();
|
||||
process.WaitForExit();
|
||||
process.Close();
|
||||
DataList.RemoveAt(SelectedIndex);
|
||||
GlobalValues.Success("操作成功");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
GlobalValues.Error($"结束进程失败:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void StartScanCmdFunc(object obj)
|
||||
{
|
||||
Enabled1 = false;
|
||||
Enabled2 = false;
|
||||
ProgressValue = 0;
|
||||
DataList.Clear();
|
||||
new Thread(() =>
|
||||
{
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo("netstat", "-ano")
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
string result = "";
|
||||
using (Process process = Process.Start(startInfo))
|
||||
{
|
||||
using (StreamReader reader = process.StandardOutput)
|
||||
{
|
||||
result = reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
List<string> lines = result.Split('\n').Select(it => it.Trim('\r').Trim()).Where(it => !it.IsNullOrEmpty()).ToList();
|
||||
List<ScanResult> results = new List<ScanResult>();
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string[] splitArray = line.Split(' ').Where(it => !it.IsNullOrEmpty()).ToArray();
|
||||
if (!line.StartsWith("TCP") && !line.StartsWith("UDP"))
|
||||
continue;
|
||||
if (splitArray.Length == 5)
|
||||
{
|
||||
int pid;
|
||||
bool flag = int.TryParse(splitArray[4], out pid);
|
||||
if (!flag)
|
||||
continue;
|
||||
if (!splitArray[1].Contains(":"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string[] splitArray2 = splitArray[1].Split(':');
|
||||
int port;
|
||||
flag = int.TryParse(splitArray2[1], out port);
|
||||
if (!flag)
|
||||
continue;
|
||||
results.Add(new ScanResult
|
||||
{
|
||||
Protocol = splitArray[0],
|
||||
LocalAddress = splitArray[1],
|
||||
Port = port,
|
||||
RemoteAddress = splitArray[2],
|
||||
State = splitArray[3],
|
||||
PID = pid,
|
||||
ProcessName = ""
|
||||
});
|
||||
}
|
||||
else if (splitArray.Length == 4)
|
||||
{
|
||||
int pid;
|
||||
bool flag = int.TryParse(splitArray[3], out pid);
|
||||
if (!flag)
|
||||
continue;
|
||||
if (!splitArray[1].Contains(":"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string[] splitArray2 = splitArray[1].Split(':');
|
||||
int port;
|
||||
flag = int.TryParse(splitArray2[1], out port);
|
||||
if (!flag)
|
||||
continue;
|
||||
results.Add(new ScanResult
|
||||
{
|
||||
Protocol = splitArray[0],
|
||||
LocalAddress = splitArray[1],
|
||||
Port = port,
|
||||
RemoteAddress = splitArray[2],
|
||||
State = "",
|
||||
PID = pid,
|
||||
ProcessName = ""
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
results = results.OrderBy(it => it.Port).ToList();
|
||||
|
||||
Dictionary<int, string> pidName = new Dictionary<int, string>();
|
||||
foreach (ScanResult scan in results)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pidName.ContainsKey(scan.PID))
|
||||
{
|
||||
scan.ProcessName = pidName[scan.PID];
|
||||
}
|
||||
else
|
||||
{
|
||||
Process process = Process.GetProcessById(scan.PID);
|
||||
if (process != null)
|
||||
{
|
||||
pidName.Add(scan.PID, process.ProcessName);
|
||||
scan.ProcessName = process.ProcessName;
|
||||
}
|
||||
}
|
||||
|
||||
Dispatcher.UIThread.Invoke(new Action(() =>
|
||||
{
|
||||
DataList.Add(scan);
|
||||
}));
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispatcher.UIThread.Invoke(new Action(() =>
|
||||
{
|
||||
DataList.Add(scan);
|
||||
}));
|
||||
}
|
||||
}
|
||||
Dispatcher.UIThread.Invoke(new Action(() =>
|
||||
{
|
||||
Enabled1 = true;
|
||||
Enabled2 = true;
|
||||
}));
|
||||
}).Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ScanResult
|
||||
{
|
||||
public string Protocol { get; set; }
|
||||
public string LocalAddress { get; set; }
|
||||
|
||||
public int Port { get; set; }
|
||||
public string RemoteAddress { get; set; }
|
||||
public string State { get; set; }
|
||||
public int PID { get; set; }
|
||||
public string ProcessName { get; set; }
|
||||
}
|
||||
}
|
||||
13
常用工具集/ViewModels/02网络相关/端口扫描ViewModel.cs
Normal file
13
常用工具集/ViewModels/02网络相关/端口扫描ViewModel.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using 常用工具集.Base;
|
||||
|
||||
namespace 常用工具集.ViewModel._02网络相关
|
||||
{
|
||||
public class 端口扫描ViewModel : ViewModelBase
|
||||
{
|
||||
}
|
||||
}
|
||||
241
常用工具集/ViewModels/02网络相关/网络状态检测ViewModel.cs
Normal file
241
常用工具集/ViewModels/02网络相关/网络状态检测ViewModel.cs
Normal file
@@ -0,0 +1,241 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Threading;
|
||||
using Ursa.Controls;
|
||||
using 常用工具集.Base;
|
||||
|
||||
namespace 常用工具集.ViewModel._02网络相关
|
||||
{
|
||||
public class 网络状态检测ViewModel : ViewModelBase
|
||||
{
|
||||
#region 数据
|
||||
public ObservableCollection<MyPingStatus> PingStatus { get; set; }
|
||||
|
||||
private int ip1 { get; set; } = 172;
|
||||
public int IP1 { get { return ip1; } set { ip1 = value; SetTip(); NotifyPropertyChanged(); } }
|
||||
private int ip2 { get; set; } = 16;
|
||||
public int IP2 { get { return ip2; } set { ip2 = value; SetTip(); NotifyPropertyChanged(); } }
|
||||
private int ip3 { get; set; } = 0;
|
||||
public int IP3 { get { return ip3; } set { ip3 = value; SetTip(); NotifyPropertyChanged(); } }
|
||||
#endregion
|
||||
|
||||
public DelegateCommand Button1Cmd { get; set; }
|
||||
public DelegateCommand Button2Cmd { get; set; }
|
||||
public 网络状态检测ViewModel()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
PingStatus = new ObservableCollection<MyPingStatus>();
|
||||
for (int i = 1; i <= 255; i++)
|
||||
{
|
||||
PingStatus.Add(new MyPingStatus
|
||||
{
|
||||
Index = i,
|
||||
IpAddress = $"{IP1}.{IP2}.{IP3}.{i}",
|
||||
Color = "#FFFF80",
|
||||
Tip = $"{IP1}.{IP2}.{IP3}.{i}",
|
||||
Status = false
|
||||
});
|
||||
}
|
||||
}
|
||||
threadList = new List<MyThread>();
|
||||
SetTip();
|
||||
Button1Cmd = new DelegateCommand(Button1CmdFunc);
|
||||
Button2Cmd = new DelegateCommand(Button2CmdFunc);
|
||||
}
|
||||
|
||||
|
||||
private List<MyThread> threadList;
|
||||
private void Button1CmdFunc(object obj)
|
||||
{
|
||||
lock (pingLock)
|
||||
{
|
||||
if (IPPool.Count > 0)
|
||||
{
|
||||
MessageBox.ShowAsync("上一次操作还没结束,请等待完成后继续");
|
||||
return;
|
||||
}
|
||||
}
|
||||
lock (_lock)
|
||||
{
|
||||
SetColor("#FFFF80");//开始之前清除一下
|
||||
}
|
||||
foreach (MyThread myThread in threadList)
|
||||
{
|
||||
myThread.Stop();
|
||||
myThread.OnSendResult -= Thread_OnSendResult;
|
||||
}
|
||||
threadList.Clear();
|
||||
lock (_lock)
|
||||
{
|
||||
for (int i = 1; i <= 255; i++)
|
||||
{
|
||||
IPPool.Add(i);
|
||||
}
|
||||
}
|
||||
string ip = $"{IP1}.{IP2}.{IP3}.";
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
MyThread thread = new MyThread(ip);
|
||||
thread.OnSendResult += Thread_OnSendResult;
|
||||
thread.Start();
|
||||
threadList.Add(thread);
|
||||
}
|
||||
}
|
||||
|
||||
private void Thread_OnSendResult(int endIndex, bool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
SetColor(endIndex, "#00FF00");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetColor(endIndex, "#FF0000");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Button2CmdFunc(object obj)
|
||||
{
|
||||
lock (pingLock)
|
||||
{
|
||||
if (IPPool.Count > 0)
|
||||
{
|
||||
MessageBox.ShowAsync("上一次操作还没结束,请等待完成后继续");
|
||||
return;
|
||||
}
|
||||
}
|
||||
lock (_lock)
|
||||
{
|
||||
SetColor("#FFFF80");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置提示
|
||||
/// </summary>
|
||||
private void SetTip()
|
||||
{
|
||||
foreach (MyPingStatus status in PingStatus)
|
||||
{
|
||||
status.Tip = $"{IP1}.{IP2}.{IP3}.{status.Index}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置提示
|
||||
/// </summary>
|
||||
private void SetColor(string color)
|
||||
{
|
||||
foreach (MyPingStatus status in PingStatus)
|
||||
{
|
||||
status.Color = color;
|
||||
}
|
||||
}
|
||||
internal static List<int> IPPool = new List<int>();
|
||||
internal static object pingLock = new object();
|
||||
internal object _lock = new object();
|
||||
private void SetColor(int index, string color)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
foreach (MyPingStatus status in PingStatus)
|
||||
{
|
||||
if (status.Index == index)
|
||||
{
|
||||
status.Color = color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class MyPingStatus : ViewModelBase
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public string Color { get; set; }
|
||||
public string Tip { get; set; }
|
||||
|
||||
public string IpAddress { get; set; }
|
||||
|
||||
public bool Status { get; set; }
|
||||
}
|
||||
|
||||
|
||||
internal class MyThread
|
||||
{
|
||||
public delegate void SendResult(int endIndex, bool state);
|
||||
public event SendResult OnSendResult;
|
||||
private Thread thread;
|
||||
private string ipAddress;
|
||||
private bool stop;
|
||||
public MyThread(string ip)
|
||||
{
|
||||
this.ipAddress = ip;
|
||||
}
|
||||
|
||||
public MyThread Start()
|
||||
{
|
||||
thread = new Thread(() =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (stop)
|
||||
break;
|
||||
//从IP池取出一个
|
||||
int ipIndex = 0;
|
||||
lock (网络状态检测ViewModel.pingLock)
|
||||
{
|
||||
if (网络状态检测ViewModel.IPPool.Count > 0)
|
||||
{
|
||||
ipIndex = 网络状态检测ViewModel.IPPool[0];
|
||||
网络状态检测ViewModel.IPPool.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
if (ipIndex == 0)
|
||||
break;
|
||||
bool flag = Ping($"{ipAddress}{ipIndex}");
|
||||
OnSendResult?.Invoke(ipIndex, flag);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex is ThreadInterruptedException)
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.Start();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
stop = true;
|
||||
thread.Interrupt();
|
||||
}
|
||||
|
||||
private bool Ping(string ip)
|
||||
{
|
||||
byte[] bytes = new byte[32];
|
||||
for (int i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
bytes[i] = (byte)(i + 1);
|
||||
}
|
||||
|
||||
Ping ping = new Ping();
|
||||
if (ping.Send(ip, 300, bytes, new PingOptions { Ttl = 255 }).Status == IPStatus.Success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user