起源
https://github.com/Tlaster/YourAV
在github发现一个古老的项目,通过在安全中心注册一个杀毒软件,来让windef自动关闭。通过这个项目也让我知道了windef是如何知道第三方杀软存在,并且关闭的。之前我的猜测是杀软厂家向微软申请了证书,windef通过这个证书来判断是否存在第三方杀软的。现在才发现,没这么麻烦。
项目测试过已经失效了,他还是使用的wmi,但是wmi已经是在powershell问世之前的东西了,他本身都过时了,针对他的操作更失效了肯定。
核心代码
思路就是:遍历数据库,删除所有的非windef杀软实例,然后根据个人的输入(AddAntivirus(string displayName, string instanceGuid)
这个函数)添加自定义的杀软实例。以此达到目的。
private static readonly string wmipathstr = @"\\" + Environment.MachineName + @"\root\SecurityCenter:AntiVirusProduct";
public static bool RemoveAllAntivirus()
{
try
{
// 从上述数据库的AntivirusProduct表中搜索所有条目
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmipathstr, "SELECT * FROM AntivirusProduct");
ManagementObjectCollection instances = searcher.Get();
// 不是windef的就删掉
foreach (ManagementObject obj in instances)
if (obj.GetPropertyValue("displayName").ToString() != "Windows Defender")
obj.Delete();
return true;
}
catch
{
return false;
}
}
public static bool AddAntivirus(string displayName, string instanceGuid)
{
try
{
// 创建新实例
ManagementClass avp = new ManagementClass(wmipathstr);
ManagementObject status = avp.CreateInstance();
// 设置新实例的信息
status.SetPropertyValue("displayName", displayName);
status.SetPropertyValue("instanceGuid", $"{{{instanceGuid}}}");
status.SetPropertyValue("productUptoDate", true);
status.SetPropertyValue("onAccessScanningEnabled", true);
// 提交新实例
status.Put();
return true;
}
catch
{
return false;
}
}
public static bool IsAntivirusInstalled()
{
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmipathstr, "SELECT * FROM AntivirusProduct");
ManagementObjectCollection instances = searcher.Get();
// 判断实例数量大于0且存在非Windows Defender的杀毒软件
return instances.Count > 0 && instances.Cast<ManagementObject>().Any(item => item.GetPropertyValue("displayName").ToString() != "Windows Defender");
}
catch
{
return false;
}
}
接下来的就是 一些辅助函数了
重启服务
public static bool RestartService(string serviceName)
{
// serviceName = “Windows Management Instrumentation”
ServiceController service = new ServiceController(serviceName);
try
{
List<ServiceController> dependencies = new List<ServiceController>();
if ((service.Status.Equals(ServiceControllerStatus.Running)) || (service.Status.Equals(ServiceControllerStatus.StartPending)))
{
FillDependencyTreeLeaves(service, dependencies);
service.Stop();
}
service.WaitForStatus(ServiceControllerStatus.Stopped);
foreach (ServiceController dependency in dependencies)
{
dependency.Start();
dependency.WaitForStatus(ServiceControllerStatus.Running);
}
return true;
}
catch
{
return false;
}
}
private static void FillDependencyTreeLeaves(ServiceController controller, List<ServiceController> controllers)
{
bool dependencyAdded = false;
foreach (ServiceController dependency in controller.DependentServices)
{
ServiceControllerStatus status = dependency.Status;
// add only those that are actually running
if (status != ServiceControllerStatus.Stopped && status != ServiceControllerStatus.StopPending)
{
dependencyAdded = true;
FillDependencyTreeLeaves(dependency, controllers);
}
}
// if no dependency has been added, the service is dependency tree's leaf
if (!dependencyAdded && !controllers.Contains(controller))
{
controllers.Add(controller);
}
}
如果服务当前正在运行,则首先获取保存该服务的所有依赖服务,然后停止要重启的服务,等待服务完全停止。
遍历依赖服务列表,启动所有依赖服务,并等待启动完毕。
FillDependencyTreeLeaves
函数用来递归获取一个服务的所有依赖服务的。
vs找不对对应的net框架版本
vs2022打开一些老项目可能会找不到项目的net框架版本,比如4.0就已经停止支持了。一般情况下是可以通过visual studio intaller去下载。
但是这里仅仅显示受支持的包,这里需要手动下载4.0,在nuget上可以找到NuGet Gallery | Microsoft.NETFramework.ReferenceAssemblies 1.0.3,当然这里最简单的就是下载一个visual2019去下载就可以了。