| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 | 
							- using System;
 
- using System.Diagnostics;
 
- using System.IO;
 
- using System.Linq;
 
- using System.Runtime.InteropServices;
 
- using Masuit.Tools.Files;
 
- using Masuit.Tools.Systems;
 
- namespace Masuit.Tools.Win32.AntiVirus;
 
- public class WindowsDefenderScanService
 
- {
 
- 	public WindowsDefenderScanService()
 
- 	{
 
- 		if (!Directory.Exists(SystemParameter.WindowsDefenderPath))
 
- 		{
 
- 			throw new PlatformNotSupportedException("Windows Defender not found");
 
- 		}
 
- 		if (!File.Exists($"{SystemParameter.WindowsDefenderPath}\\{SystemParameter.WindowsDefenderExeName}"))
 
- 		{
 
- 			throw new PlatformNotSupportedException("Windows Defender not found");
 
- 		}
 
- 	}
 
- 	/// <summary>
 
- 	/// 扫描文件流
 
- 	/// </summary>
 
- 	/// <param name="filePath"></param>
 
- 	public ScanResult ScanStream(Stream stream)
 
- 	{
 
- 		var temp = Path.Combine(Environment.GetEnvironmentVariable("temp"), SnowFlake.NewId);
 
- 		stream.SaveFile(temp);
 
- 		if (stream.CanSeek)
 
- 		{
 
- 			stream.Position = 0;
 
- 		}
 
- 		return ScanFile(temp);
 
- 	}
 
- 	/// <summary>
 
- 	/// 扫描文件
 
- 	/// </summary>
 
- 	/// <param name="filePath"></param>
 
- 	public ScanResult ScanFile(string filePath)
 
- 	{
 
- 		if (!File.Exists(filePath))
 
- 		{
 
- 			throw new FileNotFoundException();
 
- 		}
 
- 		try
 
- 		{
 
- 			//Scanning xxxxx  found 1 threats.
 
- 			//Scanning xxxxx  found no threats.
 
- 			var result = RunScanCommand(filePath);
 
- 			if (result.Contains("found no threats"))
 
- 			{
 
- 				return new ScanResult
 
- 				{
 
- 					Result = ResultCode.NotDetected,
 
- 				};
 
- 			}
 
- 			return new ScanResult
 
- 			{
 
- 				Result = ResultCode.Detected,
 
- 			};
 
- 		}
 
- 		catch (Exception ex)
 
- 		{
 
- 			return new ScanResult
 
- 			{
 
- 				Result = ResultCode.Exception,
 
- 				Msg = ex.Message
 
- 			};
 
- 		}
 
- 	}
 
- 	/// <summary>
 
- 	/// 扫描文件夹(不支持递文件夹嵌套文件夹的扫描)
 
- 	/// </summary>
 
- 	/// <param name="directoryPath"></param>
 
- 	/// <returns>如有威胁文件,只返回文件夹中有威胁的文件</returns>
 
- 	public ScanResult ScanDirectory(string directoryPath)
 
- 	{
 
- 		if (!Directory.Exists(directoryPath))
 
- 		{
 
- 			throw new DirectoryNotFoundException();
 
- 		}
 
- 		try
 
- 		{
 
- 			var files = Directory.GetFiles(directoryPath);
 
- 			//文件夹扫描
 
- 			var result = RunScanCommand(directoryPath);
 
- 			if (result.Contains("found no threats"))
 
- 			{
 
- 				return new ScanResult
 
- 				{
 
- 					Result = ResultCode.NotDetected,
 
- 				};
 
- 			}
 
- 			result = result.ToLower();
 
- 			var detectedFile = (from file in files
 
- 								let filePath = $"{file}\r\n"
 
- 								where result.Contains(filePath.ToLower())
 
- 								select file.Replace(directoryPath, "").Replace("\\", "")).ToList();
 
- 			//解析文件,找到有威胁的文件
 
- 			return new ScanResult
 
- 			{
 
- 				Result = ResultCode.Detected,
 
- 				Msg = string.Join(";", detectedFile)
 
- 			};
 
- 		}
 
- 		catch (Exception ex)
 
- 		{
 
- 			return new ScanResult
 
- 			{
 
- 				Result = ResultCode.Exception,
 
- 				Msg = ex.Message
 
- 			};
 
- 		}
 
- 	}
 
- 	/// <summary>
 
- 	/// 运行命令
 
- 	/// </summary>
 
- 	/// <param name="path"></param>
 
- 	/// <returns></returns>
 
- 	private string RunScanCommand(string path)
 
- 	{
 
- 		if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
 
- 		{
 
- 			throw new PlatformNotSupportedException();
 
- 		}
 
- 		var proc = new Process();
 
- 		try
 
- 		{
 
- 			proc.StartInfo.FileName = "cmd.exe";
 
- 			proc.StartInfo.UseShellExecute = false;
 
- 			proc.StartInfo.RedirectStandardInput = true;
 
- 			proc.StartInfo.RedirectStandardOutput = true;
 
- 			proc.StartInfo.RedirectStandardError = true;
 
- 			proc.StartInfo.CreateNoWindow = true;
 
- 			proc.Start();
 
- 			var command = $"\"{SystemParameter.WindowsDefenderPath}\\{SystemParameter.WindowsDefenderExeName}\" -Scan -ScanType 3 -File \"{path}\" -DisableRemediation";
 
- 			proc.StandardInput.WriteLine(command);
 
- 			proc.StandardInput.WriteLine("exit");
 
- 			while (!proc.HasExited)
 
- 			{
 
- 				proc.WaitForExit(1000);
 
- 			}
 
- 			return proc.StandardOutput.ReadToEnd();
 
- 		}
 
- 		catch (Exception ex)
 
- 		{
 
- 			throw new WindowsDefenderScanException();
 
- 		}
 
- 		finally
 
- 		{
 
- 			proc.Close();
 
- 			proc.Dispose();
 
- 		}
 
- 	}
 
- }
 
 
  |