Код: Выделить всё
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
INetFwRule firewallRule = firewallPolicy.Rules.OfType().Where(x => x.Name == fwRuleName).FirstOrDefault();
Я думаю, что это та строка firewallRule, потому что я буквально закомментировал каждую вторую строку в вызываемом методе (и в приложении, если уж на то пошло), и когда я наконец закомментировал эту строку, утечка прекращается. Пожалуйста, дайте мне знать, если моя логика ошибочна.
Если вы хотите проверить ее, вам нужно сделать ссылку на NetFwTypeLib, чтобы этот код работал.
Кто-нибудь знает, почему это происходит и как это исправить?
Обновление:
Вот исходный код для тех, кто верит, что я еще не все закомментировал:
Код: Выделить всё
public static void FirewallSetup(string ip, string countryCode, bool isIpsString)
{
// FirewallControl fwCtrl = new FirewallControl();
// fwCtrl.Block(ip, countryCode, isIpsString);
//}
//private void Block(string ip, string countryCode, bool isIpsString)
//{
var remoteAddresses = "*";
string fwRuleName;
bool createNewFwRule = false;
//var fwRuleSuffix = SQLControl.GetFirewallRuleSuffix(countryCode).ToString();
//if (string.IsNullOrEmpty(fwRuleSuffix) || fwRuleSuffix == "0")
//{
fwRuleName = fwRuleNamePrefix + countryCode;
//}
//else
//{
// fwRuleName = fwRuleNamePrefix + countryCode + fwRuleSuffix;
//}
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
INetFwRule firewallRule = firewallPolicy.Rules.OfType().Where(x => x.Name == fwRuleName).FirstOrDefault();
//if (firewallRule == null)
//{
// createNewFwRule = true;
//}
//else
//{
// //We need the following for creating the remoteAddresses string below
// //but, also need to count as Windows has a 5000 ip limit per rule
// remoteAddresses = firewallRule.RemoteAddresses;
// string[] aRemoteAddresses = remoteAddresses.Split(",");
// int remoteAddressesCount = aRemoteAddresses.Length;
// //Log.Debug(">>>Firewall remote addresses scope=" + remoteAddresses);
// Log.Warning(">>>" + fwRuleName + " Firewall remote addresses count:" + remoteAddressesCount);
// //5000 would be 0 to 4999 I think?
// if (remoteAddressesCount >= 4999)
// {
// //If remote ip scope is 5000, create a new fw rule
// var newFwRuleNameSuffix = SQLControl.GetNewFirewallRuleSuffix(countryCode).ToString();
// fwRuleName = fwRuleNamePrefix + countryCode + newFwRuleNameSuffix;
// createNewFwRule = true;
// }
//}
//If necessary, we create a new rule
//TODO: Create another method for this?
//if (createNewFwRule)
//{
// firewallRule = (INetFwRule)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
// firewallRule.Name = fwRuleName;
// firewallPolicy.Rules.Add(firewallRule);
// firewallRule.Description = "Block inbound traffic from " + countryCode;
// firewallRule.Profiles = (int)NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_ALL;
// firewallRule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP;
// firewallRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN;
// firewallRule.Action = NET_FW_ACTION_.NET_FW_ACTION_BLOCK;
// firewallRule.Enabled = true;
// //firewallRule.RemoteAddresses = ip;
// //firewallPolicy.Rules.Add(firewallRule); //throws error and not needed anyway
// //firewallRule.LocalPorts = "4000";
// //firewallRule.Grouping = "@firewallapi.dll,-23255";
// //firewallRule.Profiles = firewallPolicy.CurrentProfileTypes;
//}
//if (isIpsString || remoteAddresses == "*")
//{
// firewallRule.RemoteAddresses = ip;
//}
//else
//{
// firewallRule.RemoteAddresses = remoteAddresses + "," + ip;
//}
}
Теперь, когда я обдумал это и закомментировал, я также могу провести его через некоторый цикл и устранить неполадки здесь внутри компании. Это гонка...
Сервер, на котором он сейчас работает, — Windows Server 2016.
Обновление 2: Оно также воспроизводится в Windows 10. Вот весь код для воспроизведения ошибки:
Код: Выделить всё
using System;
using System.Linq;
using NetFwTypeLib;
namespace FirewallLeakTesterCore
{
class Program
{
static void Main(string[] args)
{
int count = 0;
while (count < 1000)
{
Console.WriteLine(count += 1);
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
INetFwRule firewallRule = firewallPolicy.Rules.OfType().Where(x => x.Name == "firewallRuleName").FirstOrDefault();
}
Console.ReadKey();
}
}
}
Инструменты диагностики Visual Studio:

Похоже на ошибку Microsoft? Думаю, я попробую разобраться с одним из этих профилировщиков памяти, но даже если я обнаружу проблему, что я могу сделать? Это базовый вызов базовой библиотеки Windows, и я думаю, именно поэтому некоторые люди в комментариях упускают из виду суть.
Я не прошу кого-либо профилировать мое приложение в памяти или отслеживать проблему (и никогда не просил... Я уже это делал). Я прошу альтернативные решения. Возможно, есть какая-то проблема со структурой, linq или другое утверждение, которое я мог бы полностью использовать?
Если вы хотите оставить вопрос закрытым, пусть будет так, но мне трудно поверить, что никто больше не столкнется с этим.