以编程方式将应用程序添加到Windows防火墙

时间:2008-09-22 08:13:38

标签: c# windows firewall

我有一个通过ClickOnce安装和更新的应用程序。应用程序通过FTP下载文件,因此需要作为Windows防火墙的例外添加。由于ClickOnce的工作方式,EXE的路径随每次更新而变化,因此异常也需要更改。对防火墙进行更改以使其对最终用户不可见的最佳方法是什么?

(该应用程序是用C#编写的)

8 个答案:

答案 0 :(得分:18)

不确定这是否是最佳方式,但运行netsh应该有效:

  

netsh防火墙添加allowedprogram C:\ MyApp \ MyApp.exe MyApp ENABLE

我认为这需要管理员权限,原因显而易见:)

编辑:我对ClickOnce了解不足以了解您是否可以通过它运行外部程序。

答案 1 :(得分:12)

我发现这篇文章,其中包含一个完整的包装类,用于操作Windows防火墙。 Adding an Application to the Exception list on the Windows Firewall

/// 

/// Allows basic access to the windows firewall API.
/// This can be used to add an exception to the windows firewall
/// exceptions list, so that our programs can continue to run merrily
/// even when nasty windows firewall is running.
///
/// Please note: It is not enforced here, but it might be a good idea
/// to actually prompt the user before messing with their firewall settings,
/// just as a matter of politeness.
/// 

/// 
/// To allow the installers to authorize idiom products to work through
/// the Windows Firewall.
/// 
public class FirewallHelper
{
    #region Variables
    /// 

    /// Hooray! Singleton access.
    /// 

    private static FirewallHelper instance = null;

    /// 

    /// Interface to the firewall manager COM object
    /// 

    private INetFwMgr fwMgr = null;
    #endregion
    #region Properties
    /// 

    /// Singleton access to the firewallhelper object.
    /// Threadsafe.
    /// 

    public static FirewallHelper Instance
    {
        get
        {
            lock (typeof(FirewallHelper))
            {
                if (instance == null)
                    instance = new FirewallHelper();
                return instance;
            }
        }
    }
    #endregion
    #region Constructivat0r
    /// 

    /// Private Constructor.  If this fails, HasFirewall will return
    /// false;
    /// 

    private FirewallHelper()
    {
        // Get the type of HNetCfg.FwMgr, or null if an error occurred
        Type fwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr", false);

        // Assume failed.
        fwMgr = null;

        if (fwMgrType != null)
        {
            try
            {
                fwMgr = (INetFwMgr)Activator.CreateInstance(fwMgrType);
            }
            // In all other circumnstances, fwMgr is null.
            catch (ArgumentException) { }
            catch (NotSupportedException) { }
            catch (System.Reflection.TargetInvocationException) { }
            catch (MissingMethodException) { }
            catch (MethodAccessException) { }
            catch (MemberAccessException) { }
            catch (InvalidComObjectException) { }
            catch (COMException) { }
            catch (TypeLoadException) { }
        }
    }
    #endregion
    #region Helper Methods
    /// 

    /// Gets whether or not the firewall is installed on this computer.
    /// 

    /// 
    public bool IsFirewallInstalled
    {
        get
        {
            if (fwMgr != null &&
                  fwMgr.LocalPolicy != null &&
                  fwMgr.LocalPolicy.CurrentProfile != null)
                return true;
            else
                return false;
        }
    }

    /// 

    /// Returns whether or not the firewall is enabled.
    /// If the firewall is not installed, this returns false.
    /// 

    public bool IsFirewallEnabled
    {
        get
        {
            if (IsFirewallInstalled && fwMgr.LocalPolicy.CurrentProfile.FirewallEnabled)
                return true;
            else
                return false;
        }
    }

    /// 

    /// Returns whether or not the firewall allows Application "Exceptions".
    /// If the firewall is not installed, this returns false.
    /// 

    /// 
    /// Added to allow access to this metho
    /// 
    public bool AppAuthorizationsAllowed
    {
        get
        {
            if (IsFirewallInstalled && !fwMgr.LocalPolicy.CurrentProfile.ExceptionsNotAllowed)
                return true;
            else
                return false;
        }
    }

    /// 

    /// Adds an application to the list of authorized applications.
    /// If the application is already authorized, does nothing.
    /// 

    /// 
    ///         The full path to the application executable.  This cannot
    ///         be blank, and cannot be a relative path.
    /// 
    /// 
    ///         This is the name of the application, purely for display
    ///         puposes in the Microsoft Security Center.
    /// 
    /// 
    ///         When applicationFullPath is null OR
    ///         When appName is null.
    /// 
    /// 
    ///         When applicationFullPath is blank OR
    ///         When appName is blank OR
    ///         applicationFullPath contains invalid path characters OR
    ///         applicationFullPath is not an absolute path
    /// 
    /// 
    ///         If the firewall is not installed OR
    ///         If the firewall does not allow specific application 'exceptions' OR
    ///         Due to an exception in COM this method could not create the
    ///         necessary COM types
    /// 
    /// 
    ///         If no file exists at the given applicationFullPath
    /// 
    public void GrantAuthorization(string applicationFullPath, string appName)
    {
        #region  Parameter checking
        if (applicationFullPath == null)
            throw new ArgumentNullException("applicationFullPath");
        if (appName == null)
            throw new ArgumentNullException("appName");
        if (applicationFullPath.Trim().Length == 0)
            throw new ArgumentException("applicationFullPath must not be blank");
        if (applicationFullPath.Trim().Length == 0)
            throw new ArgumentException("appName must not be blank");
        if (applicationFullPath.IndexOfAny(Path.InvalidPathChars) >= 0)
            throw new ArgumentException("applicationFullPath must not contain invalid path characters");
        if (!Path.IsPathRooted(applicationFullPath))
            throw new ArgumentException("applicationFullPath is not an absolute path");
        if (!File.Exists(applicationFullPath))
            throw new FileNotFoundException("File does not exist", applicationFullPath);
        // State checking
        if (!IsFirewallInstalled)
            throw new FirewallHelperException("Cannot grant authorization: Firewall is not installed.");
        if (!AppAuthorizationsAllowed)
            throw new FirewallHelperException("Application exemptions are not allowed.");
        #endregion

        if (!HasAuthorization(applicationFullPath))
        {
            // Get the type of HNetCfg.FwMgr, or null if an error occurred
            Type authAppType = Type.GetTypeFromProgID("HNetCfg.FwAuthorizedApplication", false);

            // Assume failed.
            INetFwAuthorizedApplication appInfo = null;

            if (authAppType != null)
            {
                try
                {
                    appInfo = (INetFwAuthorizedApplication)Activator.CreateInstance(authAppType);
                }
                // In all other circumnstances, appInfo is null.
                catch (ArgumentException) { }
                catch (NotSupportedException) { }
                catch (System.Reflection.TargetInvocationException) { }
                catch (MissingMethodException) { }
                catch (MethodAccessException) { }
                catch (MemberAccessException) { }
                catch (InvalidComObjectException) { }
                catch (COMException) { }
                catch (TypeLoadException) { }
            }

            if (appInfo == null)
                throw new FirewallHelperException("Could not grant authorization: can't create INetFwAuthorizedApplication instance.");

            appInfo.Name = appName;
            appInfo.ProcessImageFileName = applicationFullPath;
            // ...
            // Use defaults for other properties of the AuthorizedApplication COM object

            // Authorize this application
            fwMgr.LocalPolicy.CurrentProfile.AuthorizedApplications.Add(appInfo);
        }
        // otherwise it already has authorization so do nothing
    }
    /// 

    /// Removes an application to the list of authorized applications.
    /// Note that the specified application must exist or a FileNotFound
    /// exception will be thrown.
    /// If the specified application exists but does not current have
    /// authorization, this method will do nothing.
    /// 

    /// 
    ///         The full path to the application executable.  This cannot
    ///         be blank, and cannot be a relative path.
    /// 
    /// 
    ///         When applicationFullPath is null
    /// 
    /// 
    ///         When applicationFullPath is blank OR
    ///         applicationFullPath contains invalid path characters OR
    ///         applicationFullPath is not an absolute path
    /// 
    /// 
    ///         If the firewall is not installed.
    /// 
    /// 
    ///         If the specified application does not exist.
    /// 
    public void RemoveAuthorization(string applicationFullPath)
    {

        #region  Parameter checking
        if (applicationFullPath == null)
            throw new ArgumentNullException("applicationFullPath");
        if (applicationFullPath.Trim().Length == 0)
            throw new ArgumentException("applicationFullPath must not be blank");
        if (applicationFullPath.IndexOfAny(Path.InvalidPathChars) >= 0)
            throw new ArgumentException("applicationFullPath must not contain invalid path characters");
        if (!Path.IsPathRooted(applicationFullPath))
            throw new ArgumentException("applicationFullPath is not an absolute path");
        if (!File.Exists(applicationFullPath))
            throw new FileNotFoundException("File does not exist", applicationFullPath);
        // State checking
        if (!IsFirewallInstalled)
            throw new FirewallHelperException("Cannot remove authorization: Firewall is not installed.");
        #endregion

        if (HasAuthorization(applicationFullPath))
        {
            // Remove Authorization for this application
            fwMgr.LocalPolicy.CurrentProfile.AuthorizedApplications.Remove(applicationFullPath);
        }
        // otherwise it does not have authorization so do nothing
    }
    /// 

    /// Returns whether an application is in the list of authorized applications.
    /// Note if the file does not exist, this throws a FileNotFound exception.
    /// 

    /// 
    ///         The full path to the application executable.  This cannot
    ///         be blank, and cannot be a relative path.
    /// 
    /// 
    ///         The full path to the application executable.  This cannot
    ///         be blank, and cannot be a relative path.
    /// 
    /// 
    ///         When applicationFullPath is null
    /// 
    /// 
    ///         When applicationFullPath is blank OR
    ///         applicationFullPath contains invalid path characters OR
    ///         applicationFullPath is not an absolute path
    /// 
    /// 
    ///         If the firewall is not installed.
    /// 
    /// 
    ///         If the specified application does not exist.
    /// 
    public bool HasAuthorization(string applicationFullPath)
    {
        #region  Parameter checking
        if (applicationFullPath == null)
            throw new ArgumentNullException("applicationFullPath");
        if (applicationFullPath.Trim().Length == 0)
            throw new ArgumentException("applicationFullPath must not be blank");
        if (applicationFullPath.IndexOfAny(Path.InvalidPathChars) >= 0)
            throw new ArgumentException("applicationFullPath must not contain invalid path characters");
        if (!Path.IsPathRooted(applicationFullPath))
            throw new ArgumentException("applicationFullPath is not an absolute path");
        if (!File.Exists(applicationFullPath))
            throw new FileNotFoundException("File does not exist.", applicationFullPath);
        // State checking
        if (!IsFirewallInstalled)
            throw new FirewallHelperException("Cannot remove authorization: Firewall is not installed.");

        #endregion

        // Locate Authorization for this application
        foreach (string appName in GetAuthorizedAppPaths())
        {
            // Paths on windows file systems are not case sensitive.
            if (appName.ToLower() == applicationFullPath.ToLower())
                return true;
        }

        // Failed to locate the given app.
        return false;

    }

    /// 

    /// Retrieves a collection of paths to applications that are authorized.
    /// 

    /// 
    /// 
    ///         If the Firewall is not installed.
    ///   
    public ICollection GetAuthorizedAppPaths()
    {
        // State checking
        if (!IsFirewallInstalled)
            throw new FirewallHelperException("Cannot remove authorization: Firewall is not installed.");

        ArrayList list = new ArrayList();
        //  Collect the paths of all authorized applications
        foreach (INetFwAuthorizedApplication app in fwMgr.LocalPolicy.CurrentProfile.AuthorizedApplications)
            list.Add(app.ProcessImageFileName);

        return list;
    }
    #endregion
}

/// 

/// Describes a FirewallHelperException.
/// 

/// 
///
/// 
public class FirewallHelperException : System.Exception
{
    /// 

    /// Construct a new FirewallHelperException
    /// 

    /// 
    public FirewallHelperException(string message)
      : base(message)
    { }
}

ClickOnce沙箱没有任何问题。

答案 2 :(得分:11)

可以从防火墙访问数据,请查看以下文章。

真正的问题是ClickOnce沙箱是否允许这种访问?我的猜测是它没有。也许你可以使用网络服务? (有关ClickOnce中数据访问方法的详细信息,请参阅Accessing Local and Remote Data in ClickOnce Applications

答案 3 :(得分:5)

可以在The Wayback Machine上找到“将应用程序添加到Windows防火墙上的例外列表”的死链接:

http://web.archive.org/web/20070707110141/http://www.dot.net.nz/Default.aspx?tabid=42&mid=404&ctl=Details&ItemID=8

答案 4 :(得分:4)

我知道最简单的方法是使用netsh,您只需删除规则并重新创建规则,或者设置端口规则(如果已修复)。
Here是一个描述其防火墙上下文选项的页面。

答案 5 :(得分:3)

假设我们正在使用Visual Studio Installer->安装项目 - 您需要在正在安装的程序集中安装这样的安装程序类,然后确保在安装中为“主输出”添加自定义操作相。

using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.IO;
using System.Diagnostics;

namespace YourNamespace
{
    [RunInstaller(true)]
    public class AddFirewallExceptionInstaller : Installer
    {
        protected override void OnAfterInstall(IDictionary savedState)
        {
            base.OnAfterInstall(savedState);

            var path = Path.GetDirectoryName(Context.Parameters["assemblypath"]);
            OpenFirewallForProgram(Path.Combine(path, "YourExe.exe"),
                                   "Your program name for display");
        }

        private static void OpenFirewallForProgram(string exeFileName, string displayName)
        {
            var proc = Process.Start(
                new ProcessStartInfo
                    {
                        FileName = "netsh",
                        Arguments =
                            string.Format(
                                "firewall add allowedprogram program=\"{0}\" name=\"{1}\" profile=\"ALL\"",
                                exeFileName, displayName),
                        WindowStyle = ProcessWindowStyle.Hidden
                    });
            proc.WaitForExit();
        }
    }
}

答案 6 :(得分:1)

答案是您只允许受信任的软件以管理员权限运行。有时,某些软件必须具有管理员权限,并对您的系统进行敏感更改。你可能还有一个只读硬盘,否则......

答案 7 :(得分:1)

这个答案可能是迟到的。这就是我最终使用的:

http://support.microsoft.com/kb/947709