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的情况与之不同),以后有时间再补齐吧。

  文笔不太好,所以基本都是白话,望大家多多包涵,我的初心是大家可以从中学到知识,一起成长!

 

posted @ 2017-11-21 11:01  墨渊、  阅读(812)  评论(4编辑  收藏  举报