Если Вы пишите приложения для работы в Сети, то рано или поздно Вы столкнетесь с проблемой, которая на разных форумах и в различных сообществах Delphi звучит практически одинаково «Как в Delphi добавить программу в список исключений брандмауэра Windows?«, «Как в Delphi создать правило в firewall для своей программы?» и, наконец, «Как в Delphi работать с firewall Windows?«. Решение проблемы, как известно, может быть несколько и одно из них — написать батник, который будет создавать правило для вашей программы. Я же в этой статье представлю вам несколько примеров по работе с брандмауэром (firewall) Windows в Delphi с использованием Windows API, а уж какой способ работы выбрать вам (писать батник или использовать WinAPI) — решать исключительно Вам.
О чем пойдет речь в статье?
Вполне возможно, что Вы ещё только-только начинаете работу в Delphi с Сетью и ещё не до конца представляете себе в какие дебри Windows вас может завести ваш Delphi-проект. Поэтому сразу скажу, что примеры представленные в статье ниже, показывают работу с «Windows Firewall Advanced Security» или, если у Вас, как и у меня русская версия Windows, с разделом настроек в панели управления «Панель управления\Система и безопасность\Брандмауэр Windows\Дополнительные параметры«:
В разделе дополнительных настроек брандмауэра Windows мы можем создавать правила для входящих и исходящих подключений, которые будут разрешать или же, наоборот, блокировать подключения программ, подключения с различных IP-адресов и портов и так далее. И, бывают (причем не редко) такие ситуации, когда firewall Windows блокирует всё, что не разрешено (что, с точки зрения безопасности -правильно) и нам надо как-то «уведомить» брандмауэр, что наше приложение безопасно и ему можно доверять, а именно — нам требуется создать новое правило для нашего приложения. Вот об этом и другом пойдет речь в статье. Реализовывать в Delphi мы будем примеры, представленные вот в этом разделе MSDN.
Как перечислить все правила Firewall?
Пример может пригодиться в случае, когда вам необходимо проверить — было ли создано правило для вашего приложения или же вам потребуется определить не отключено ли ваше правило пользователем и так далее.
//Выводит все названия правил //AOnlyEnabled - только работающих правил procedure EnumerateFirewallRules(AStrings: TStrings; AOnlyEnabled: boolean); var CurrentProfiles: Integer; fwPolicy2: OleVariant; RulesObject: OleVariant; rule: OleVariant; oEnum: IEnumvariant; iValue: LongWord; begin if not Assigned(AStrings) then Exit; fwPolicy2 := CreateOleObject('HNetCfg.FwPolicy2'); RulesObject := fwPolicy2.Rules; CurrentProfiles := fwPolicy2.CurrentProfileTypes; oEnum := IUnknown(RulesObject._NewEnum) as IEnumvariant; while oEnum.Next(1, rule, iValue) = 0 do begin if (rule.Profiles And CurrentProfiles) <> 0 then begin if (not AOnlyEnabled) or (rule.Enabled) then AStrings.Add(rule.Name); rule := Unassigned; end; end; end;
Немного переписав этот пример, можно сделать также и чтение свойств правил. Чтобы узнать то, какими свойствами обладают правила брандмауэра Windows я рекомендую обратиться к этой ссылке MSDN.
Как добавить свое правило в firewall для приложения?
//ACaption - заголовок, который будет отображаться в списке правил CONST //Профили NET_FW_PROFILE2_DOMAIN = 1; NET_FW_PROFILE2_PRIVATE = 2; NET_FW_PROFILE2_PUBLIC = 4; //Протоколы NET_FW_IP_PROTOCOL_TCP = 6; NET_FW_IP_PROTOCOL_UDP = 17; NET_FW_IP_PROTOCOL_ICMPv4 = 1; NET_FW_IP_PROTOCOL_ICMPv6 = 58; //Направление (входящее/исходящее подключение) NET_FW_RULE_DIR_IN = 1; NET_FW_RULE_DIR_OUT = 2; //Действия (разрешать/блокировать) NET_FW_ACTION_BLOCK = 0; NET_FW_ACTION_ALLOW = 1; //AExePath - полный путь к exe-файлу //AIncoming - правило для входящих подключений procedure AddFirewallRule(const ACaption, AExePath: string; AIncoming: boolean); var Profile: Integer; Policy2: OleVariant; RObject: OleVariant; NewRule: OleVariant; begin //создаем правило для всех профилей Profile := NET_FW_PROFILE2_PRIVATE OR NET_FW_PROFILE2_PUBLIC OR NET_FW_PROFILE2_DOMAIN; Policy2 := CreateOleObject('HNetCfg.FwPolicy2'); RObject := Policy2.Rules; NewRule := CreateOleObject('HNetCfg.FWRule'); //задаем заголовок и описание правила NewRule.Name := ACaption; NewRule.Description := ACaption; //указываем путь к приложению NewRule.ApplicationName := AExePath; //указываем протоков - TCP NewRule.Protocol := NET_FW_IP_PROTOCOL_TCP; //Включаем правило NewRule.Enabled := True; //Задаем группу NewRule.Grouping := 'My Programm Group'; NewRule.Profiles := Profile; //Правило "Разрешить" NewRule.Action := NET_FW_ACTION_ALLOW; //Входящее/Исходящее правило if AIncoming then NewRule.Direction:=NET_FW_RULE_DIR_IN else NewRule.Direction:=NET_FW_RULE_DIR_OUT; //Добавляем в список RObject.Add(NewRule); end;
Пример вызова:
AddFirewallRule('My Rule', ParamStr(0), True);
Результат вызова:
Как добавить свое правило в firewall для порта?
Правило создается аналогичным образом, как и в предыдущем примере:
procedure AddFirewallPortRule(const ACaption: string; APort: word; AIncoming: boolean); var Profile: Integer; Policy2: OleVariant; RObject: OleVariant; NewRule: OleVariant; begin //создаем правило для всех профилей Profile := NET_FW_PROFILE2_PRIVATE OR NET_FW_PROFILE2_PUBLIC OR NET_FW_PROFILE2_DOMAIN; Policy2 := CreateOleObject('HNetCfg.FwPolicy2'); RObject := Policy2.Rules; NewRule := CreateOleObject('HNetCfg.FWRule'); //задаем заголовок и описание правила NewRule.Name := ACaption; NewRule.Description := ACaption; //указываем путь к приложению NewRule.Protocol := NET_FW_IP_PROTOCOL_TCP; NewRule.LocalPorts:=APort; //Включаем правило NewRule.Enabled := True; //Задаем группу NewRule.Grouping := 'My Interface Group'; NewRule.Profiles := Profile; //Правило "Разрешить" NewRule.Action := NET_FW_ACTION_ALLOW; //Входящее/Исходящее правило if AIncoming then NewRule.Direction:=NET_FW_RULE_DIR_IN else NewRule.Direction:=NET_FW_RULE_DIR_OUT; //Добавляем в список RObject.Add(NewRule); end;
Пример вызова:
AddFirewallPortRule('My port rule', 8080, False);
Результат вызова:
Аналогичным образом, можно создавать различные правила для сервисов, указывать свои группы правил и т.д. Думаю, что приведенных выше примеров будет вполне достаточно, чтобы Вы, в случае необходимости, могли определить любое правило для Firewall в Delphi и добавить его в список, используя Windows API.
Как отключить firewall?
Отключить брандмауэр (firewall) Windows, используя Delphi, можно так:
procedure DisableFirewall; var fwPolicy2 : OleVariant; begin fwPolicy2 := CreateOleObject('HNetCfg.FwPolicy2'); fwPolicy2.FirewallEnabled[NET_FW_PROFILE2_DOMAIN]:= False; fwPolicy2.FirewallEnabled[NET_FW_PROFILE2_PRIVATE]:= False; fwPolicy2.FirewallEnabled[NET_FW_PROFILE2_PUBLIC]:= False; end;
Как приложению запросить права администратора?
Опять же, довольно распространенный вопрос, возникающий у разработчиков, в особенности, когда дело касается изменения каких-либо настроек операционной системы (в том числе и встроенного брандмауэра). И, надо сказать, что в Сети много примеров на этот счёт. В основном всё сводится к созданию своего манифеста для приложения и внедрения его в проект через ресурсы. Эти решения предлагались в те времена, когда Delphi 7 была самой новой и современной IDE. Запросить приложению права администратора в Delphi 10.1 Berlin (и я полагаю, что и в более ранних версиях) очень просто. Решение представлено на рисунке ниже:
Собираем проект и радуемся, что наше приложение при запуске запрашивает права администратора.
Надеюсь, что представленные выше примеры помогут вам быстрее разобраться с вопросами, касающимися работы с брандмауэром (firewall) Windows в Delphi и избежать лишних проблем с работой ваших приложений в Сети. До новых встреч на страницах блога webdelphi.ru.
Книжная полка
![]() |
Описание Подробно рассматривается библиотека FM, позволяющая создавать полнофункциональное программное обеспечение для операционных систем Windows и OS X, а также для смартфонов и планшетных компьютеров, работающих под управлением Android и iOS
|
![]() |
![]() |
Описание: Рассмотрены практические вопросы по разработке клиент-серверных приложений в среде Delphi 7 и Delphi 2005 с использованием СУБД MS SQL Server 2000, InterBase и Firebird. Приведена информация о теории построения реляционных баз данных и языке SQL. Освещены вопросы эксплуатации и администрирования СУБД.
|
![]() |
![]() |
Название: О чем не пишут в книгах по Delphi
Описание: Рассмотрены малоосвещенные вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные режимы их работы, особенности для протоколов TCP и UDP и др.
|
![]() |









А как быть, если мне надо временно повысить права для осуществления определенной операции, например для пинга посредством компонента TIdIcmpClient (из Indy библиотеки) ?
«Собираем проект и радуемся, что наше приложение при запуске запрашивает права администратора.»
Спасибо!