Get Windows Firewall prompt for console app but not service

风格不统一 提交于 2019-12-06 20:44:24
Raheel Khan

Services execute under restricted environments and are allowed to have very little or no interaction with the UI. His answer covers all the reasoning and here is how to achieve the same.

I would recommend adding an additional project to your solution (let's call it Configurator) which can be launched as part of the installation process. As far as I remember, adding a rule to the firewall requires administrative privileges. Here are the steps:

  • Create the Configurator project as a Console or WinForms application. No UI is needed here.
  • Add an application manifest file to the Configurator project. right-click project, Add > New Item > Application Manifest File. Change the <requestedExecutionLevel> tag to read <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />.
  • Add the output of the Configurator project to your setup/deployment project.
  • Select the deployment project and navigate to the Custom Actions tab. Add a new custom action under the Commit node and make it point to the output of the Configurator project.
  • In the Configurator project, add a reference to NetFwTypeLib from COM references.
  • Add the code below to the Configurator project.

Modify the Main method of the Configurator project to return an int (0 for success, non-zero for failure) and use the following code. Note that I've pasted this from my project directly so you may need to fix some decleration errors, etc.

private static int Main (string [] args)
{
    var application = new NetFwAuthorizedApplication()
    {
        Name = "MyService",
        Enabled = true,
        RemoteAddresses = "*",
        Scope = NET_FW_SCOPE_.NET_FW_SCOPE_ALL,
        IpVersion = NET_FW_IP_VERSION_.NET_FW_IP_VERSION_ANY,
        ProcessImageFileName = "ServiceAssemblyName.dll",
    };

    return (FirewallUtilities.AddApplication(application, out exception) ? 0 : -1);
}

namespace MySolution.Configurator.Firewall
{
    using System;
    using System.Linq;
    using NetFwTypeLib;

    public sealed class NetFwAuthorizedApplication:
        INetFwAuthorizedApplication
    {
        public string Name { get; set; }
        public bool Enabled { get; set; }
        public NET_FW_SCOPE_ Scope { get; set; }
        public string RemoteAddresses { get; set; }
        public string ProcessImageFileName { get; set; }
        public NET_FW_IP_VERSION_ IpVersion { get; set; }

        public NetFwAuthorizedApplication ()
        {
            this.Name = "";
            this.Enabled = false;
            this.RemoteAddresses = "";
            this.ProcessImageFileName = "";
            this.Scope = NET_FW_SCOPE_.NET_FW_SCOPE_ALL;
            this.IpVersion = NET_FW_IP_VERSION_.NET_FW_IP_VERSION_ANY;
        }

        public NetFwAuthorizedApplication (string name, bool enabled, string remoteAddresses, NET_FW_SCOPE_ scope, NET_FW_IP_VERSION_ ipVersion, string processImageFileName)
        {
            this.Name = name;
            this.Scope = scope;
            this.Enabled = enabled;
            this.IpVersion = ipVersion;
            this.RemoteAddresses = remoteAddresses;
            this.ProcessImageFileName = processImageFileName;
        }

        public static NetFwAuthorizedApplication FromINetFwAuthorizedApplication (INetFwAuthorizedApplication application)
        {
            return (new NetFwAuthorizedApplication(application.Name, application.Enabled, application.RemoteAddresses, application.Scope, application.IpVersion, application.ProcessImageFileName));
        }
    }
}

namespace MySolution.Configurator.Firewall
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using NetFwTypeLib;

    public static class FirewallUtilities
    {
        public static bool GetApplication (string processImageFileName, out INetFwAuthorizedApplication application, out Exception exception)
        {
            var result = false;
            var comObjects = new Stack<object>();

            exception = null;
            application = null;

            if (processImageFileName == null) { throw (new ArgumentNullException("processImageFileName")); }
            if (processImageFileName.Trim().Length == 0) { throw (new ArgumentException("The argument [processImageFileName] cannot be empty.", "processImageFileName")); }

            try
            {
                var type = Type.GetTypeFromProgID("HNetCfg.FwMgr", true);

                try
                {
                    var manager = (INetFwMgr) Activator.CreateInstance(type);
                    comObjects.Push(manager);

                    try
                    {
                        var policy = manager.LocalPolicy;
                        comObjects.Push(policy);

                        var profile = policy.CurrentProfile;
                        comObjects.Push(profile);

                        var applications = profile.AuthorizedApplications;
                        comObjects.Push(applications);

                        foreach (INetFwAuthorizedApplication app in applications)
                        {
                            comObjects.Push(app);

                            if (string.Compare(app.ProcessImageFileName, processImageFileName, true, CultureInfo.InvariantCulture) == 0)
                            {
                                result = true;
                                application = NetFwAuthorizedApplication.FromINetFwAuthorizedApplication(app);

                                break;
                            }
                        }

                        if (!result) { throw (new Exception("The requested application was not found.")); }
                    }
                    catch (Exception e)
                    {
                        exception = e;
                    }
                }
                catch (Exception e)
                {
                    exception = e;
                }
                finally
                {
                    while (comObjects.Count > 0)
                    {
                        ComUtilities.ReleaseComObject(comObjects.Pop());
                    }
                }
            }
            catch (Exception e)
            {
                exception = e;
            }
            finally
            {
            }

            return (result);
        }

        public static bool AddApplication (INetFwAuthorizedApplication application, out Exception exception)
        {
            var result = false;
            var comObjects = new Stack<object>();

            exception = null;

            if (application == null) { throw (new ArgumentNullException("application")); }

            try
            {
                var type = Type.GetTypeFromProgID("HNetCfg.FwMgr", true);

                try
                {
                    var manager = (INetFwMgr) Activator.CreateInstance(type);
                    comObjects.Push(manager);

                    try
                    {
                        var policy = manager.LocalPolicy;
                        comObjects.Push(policy);

                        var profile = policy.CurrentProfile;
                        comObjects.Push(profile);

                        var applications = profile.AuthorizedApplications;
                        comObjects.Push(applications);

                        applications.Add(application);

                        result = true;
                    }
                    catch (Exception e)
                    {
                        exception = e;
                    }
                }
                catch (Exception e)
                {
                    exception = e;
                }
                finally
                {
                    while (comObjects.Count > 0)
                    {
                        ComUtilities.ReleaseComObject(comObjects.Pop());
                    }
                }
            }
            catch (Exception e)
            {
                exception = e;
            }
            finally
            {
            }

            return (result);
        }

        public static bool RemoveApplication (string processImageFileName, out Exception exception)
        {
            var result = false;
            var comObjects = new Stack<object>();

            exception = null;

            if (processImageFileName == null) { throw (new ArgumentNullException("processImageFileName")); }
            if (processImageFileName.Trim().Length == 0) { throw (new ArgumentException("The argument [processImageFileName] cannot be empty.", "processImageFileName")); }

            try
            {
                var type = Type.GetTypeFromProgID("HNetCfg.FwMgr", true);

                try
                {
                    var manager = (INetFwMgr) Activator.CreateInstance(type);
                    comObjects.Push(manager);

                    try
                    {
                        var policy = manager.LocalPolicy;
                        comObjects.Push(policy);

                        var profile = policy.CurrentProfile;
                        comObjects.Push(profile);

                        var applications = profile.AuthorizedApplications;
                        comObjects.Push(applications);

                        applications.Remove(processImageFileName);

                        result = true;
                    }
                    catch (Exception e)
                    {
                        exception = e;
                    }
                }
                catch (Exception e)
                {
                    exception = e;
                }
                finally
                {
                    while (comObjects.Count > 0)
                    {
                        ComUtilities.ReleaseComObject(comObjects.Pop());
                    }
                }
            }
            catch (Exception e)
            {
                exception = e;
            }
            finally
            {
            }

            return (result);
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!