C#操作防火墙控制电脑某些软件联网
问题:
目前公司软件刚由单机软件更改为联网软件,许多客户反映希望能够有一个功能来控制电脑上某些必用软件,如qq,公司软件联网,而其他不必要的如网页,游戏等软件不允许联网,于是向公司反映希望可以有一个功能能够实现这种需求。
开始思路:
刚开始接到任务的时候首先想到是控制防火墙来进行此项操作。于是打开自己电脑的防火墙,设置了出站规则——新建规则——禁用所有程序联网,然后单独设置两个例外,测试结果为所有程序都连不上网,于是这个思路放弃。
然后思考用c#写程序来监控任务管理器中程序的添加,如果不是qq或者是我们软件的话,就会kill程序,结果杀伤力巨大,就连打开我的电脑都打不开了,于是这个思路也走不通。
最后还是回到了防火墙的层面:首先新建规则—禁用1—65535的所有端口,然后开启qq所用的4000—4100端口和软件所用的8080端口。测试结果成功。
参考代码:
https://www.cnblogs.com/shenblogs/archive/2016/05/13/5489161.html 写的很全,并且有关闭防火墙的功能
c#程序:
主要添加引用:
1.com组件NetFwTypeLib
2.System.ServiceProcess
应注意:在添加禁用端口的规则时,应该注意要先添加规则的协议为TCP还是Udp,不然可能会报:值不在预期的范围内。
主要程序如下:
1 using Microsoft.Win32; 2 using NetFwTypeLib; 3 using System; 4 using System.Collections.Generic; 5 using System.Diagnostics; 6 using System.Linq; 7 using System.ServiceProcess; 8 using System.Text; 9 using System.Threading.Tasks; 10 11 namespace Control_Firewall 12 { 13 class Program 14 { 15 RegistryKey firekey; 16 //获取防火墙名称 17 string firewallname = ""; 18 //电脑名称 19 string versionname = ""; 20 //获取电脑版本名称 21 public string getsysversion() 22 { 23 RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"Software\\Microsoft\\Windows NT\\CurrentVersion"); 24 versionname = rk.GetValue("ProductName").ToString(); 25 rk.Close(); 26 return versionname; 27 } 28 //根据电脑类型来操作防火墙打开 29 public void openfire(string versionname) 30 { 31 if (versionname.Contains("XP")) 32 { 33 firewallname = "SharedAccess"; 34 firekey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\\CurrentControlSet\\Services\\SharedAccess", true); 35 } 36 else 37 { 38 firewallname = "MpsSvc"; 39 firekey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\\CurrentControlSet\\Services\\MpsSvc", true); 40 } 41 //获取启动类型为禁止还是自动 42 string start = firekey.GetValue("Start").ToString(); 43 if (start == "4") { 44 ProcessStartInfo objProInfo = new ProcessStartInfo(); 45 objProInfo.FileName = "cmd.exe"; 46 objProInfo.CreateNoWindow = false; 47 objProInfo.WindowStyle = ProcessWindowStyle.Hidden; 48 objProInfo.Arguments = "/c sc config " + firewallname + " start= " + "auto"; 49 Process.Start(objProInfo); 50 //挂起线程1s后启动服务 51 System.Threading.Thread.Sleep(1000); 52 } 53 firekey.Close(); 54 //判断防火墙是否启动了 55 ServiceController sc = new ServiceController(firewallname); 56 //如果防火墙未启动则启动 57 if (sc.Status.Equals(ServiceControllerStatus.Stopped) || sc.Status.Equals(ServiceControllerStatus.StopPending)) 58 { 59 sc.Start(); 60 } 61 //暂时不用 62 if (versionname.Contains("XP")) 63 { 64 RegistryKey rekey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\StandardProfile", true); 65 var Enablefilewall = rekey.GetValue("EnableFirewall").ToString(); 66 if (Enablefilewall == "0") 67 { 68 rekey.SetValue("EnableFirewall", 1); 69 } 70 rekey.Close(); 71 } 72 else 73 { 74 INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2")); 75 // 启用<高级安全Windows防火墙> - 专有配置文件的防火墙 76 firewallPolicy.set_FirewallEnabled(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE, true); 77 // 启用<高级安全Windows防火墙> - 公用配置文件的防火墙 78 firewallPolicy.set_FirewallEnabled(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PUBLIC, true); 79 } 80 } 81 //为防火墙添加出站规则 82 public void handle(string name) 83 { 84 //目前不用 85 if (name.Contains("XP")) 86 { 87 INetFwAuthorizedApplication Fwapp = (INetFwAuthorizedApplication)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwAuthorizedApplication")); 88 } 89 90 else 91 { 92 // 1. 创建实例,阻止所有的出站连接 93 INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2")); 94 //启用或禁用<高级安全Windows防火墙> - 专有配置文件的出站连接 95 firewallPolicy.set_DefaultOutboundAction(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE, NET_FW_ACTION_.NET_FW_ACTION_ALLOW); 96 //启用或禁用<高级安全Windows防火墙> - 公用配置文件的出站连接 97 firewallPolicy.set_DefaultOutboundAction(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PUBLIC, NET_FW_ACTION_.NET_FW_ACTION_ALLOW); 98 //创建三个出站规则来控制程序联网 99 INetFwRule2 qqRule = (INetFwRule2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule")); 100 INetFwRule2 conductRule = (INetFwRule2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule")); 101 INetFwRule2 stopallRule = (INetFwRule2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule")); 102 stopallRule.Name = "禁用所有端口号"; 103 stopallRule.Description = "关闭所有可用端口"; 104 stopallRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT; 105 stopallRule.Action = NET_FW_ACTION_.NET_FW_ACTION_BLOCK; 106 stopallRule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP; 107 stopallRule.Enabled = true; 108 stopallRule.RemotePorts = "1-65535"; 109 110 //开启qq端口 111 qqRule.Name = "启用qq"; 112 qqRule.Description = "开启qq所用的4000-4100端口"; 113 qqRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT; 114 qqRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW; 115 qqRule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP; 116 qqRule.Enabled = true; 117 qqRule.RemotePorts = "4000-4100"; 118 119 //开启所用软件端口 120 conductRule.Name = "软件"; 121 conductRule.Description = "开启软件所用的8080端口"; 122 conductRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT; 123 conductRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW; 124 conductRule.Enabled = true; 125 conductRule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP; 126 conductRule.RemotePorts = "8080"; 127 firewallPolicy.Rules.Add(stopallRule); 128 firewallPolicy.Rules.Add(qqRule); 129 firewallPolicy.Rules.Add(conductRule); 130 //添加成功,显示成功标志 131 Console.WriteLine("all done"); 132 } 133 } 134 static void Main(string[] args) 135 { 136 137 Program p = new Program(); 138 string sysversion = p.getsysversion(); 139 p.openfire(sysversion); 140 p.handle(sysversion); 141 } 142 } 143 }
代码写的比较急,所以有些地方写的不太好,并且目前所面向的系统主要是win7系统,因此只写了win7的情况(xp的情况与之不同),以后有时间再补齐吧。
文笔不太好,所以基本都是白话,望大家多多包涵,我的初心是大家可以从中学到知识,一起成长!
作者:墨染、
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。