2008-09-22 3 views
20

У меня есть приложение, которое устанавливается и обновляется с помощью ClickOnce. Приложение загружает файлы по FTP и поэтому должно быть добавлено в качестве исключения для брандмауэра Windows. Из-за того, как работает ClickOnce, путь к EXE изменяется с каждым обновлением, поэтому также необходимо изменить исключение. Какой был бы лучший способ внести изменения в брандмауэр, чтобы был невидимым конечному пользователю?Программно добавьте приложение в брандмауэр Windows

(Приложение написано на C#)

+0

У меня такая же проблема, но с другим программным обеспечением безопасности (а не только с брандмауэром Windows) – Jamiegs 2011-06-21 19:53:38

ответ

9

Я нашел эту статью, которая имеет полный класс оболочки, включенный для управления брандмауэром 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 песочнице не представляет каких-либо проблем.

18

Не уверен, что это лучший способ, но работает netsh должно работать:

Netsh брандмауэра добавить allowedprogram C: \ MyApp \ MyApp.exe MyApp ВКЛЮЧИТЬ

Я думаю, что это требует разрешений администратора, хотя, по понятным причинам :)

Edit: Я просто не знаю достаточно о ClickOnce, чтобы узнать, можете ли вы запускать через него внешние программы.

+0

Мне лично нравится это решение. Гораздо проще вызывать такой внешний процесс, как перебираться с помощью API Windows, особенно при использовании таких вещей, как Qt/C++. – jocull 2010-10-12 01:55:12

+7

Это зависит от ОС и не работает с Win7 (его устаревшим). Вам нужно сделать что-то более уродливое: netsh advfirewall firewall добавить имя правила = «разрешить мессенджер» dir = in program = «c: \ program files \ messenger \ msmsgs.exe» security = authnoencap action = allow – 2012-02-01 22:00:56

+1

Просто добавьте, для полноты использования, развертывание ClickOnce не ограничивает возможности вашего приложения после установки, хотя может попробовать проверить наличие обновлений при запуске. – Basic 2014-10-08 01:37:04

11

Доступ к данным из брандмауэра возможен, см. Следующие статьи.

Реальный вопрос делает песочница ClickOnce позволяет такой доступ? Я предполагаю, что это не так. Может быть, вы можете использовать веб-сервис? (Для получения более подробной информации о методах доступа к данным в ClickOnce см Accessing Local and Remote Data in ClickOnce Applications)

+0

Если у вас возникли проблемы с добавлением ссылки hnetcfg на vs2010, проверьте эту ссылку http://connect.microsoft.com/VisualStudio/feedback/details/575401/interop-netfwtypelib-dll-change – Alexandre 2011-08-08 13:50:17

+0

Я получаю отказ от доступа, который я упомянул здесь http://stackoverflow.com/questions/8605710/get-my-application-to-be-allowed-access-through-firewall-using-c-sharp – PUG 2011-12-22 16:06:37

3

Самый простой способ я знаю, будет использовать netsh, вы можете просто удалить правило и создать его повторно, или настроить правила порта, если ваша фиксированный.
Here - это страница, описывающая параметры контекста брандмауэра.

+0

** netsh ** является ОС-специфическим. Вы не можете использовать 1 команду netsh как на сервере 2003, так и на сервере 2008 года. – Achilles 2011-07-13 17:14:07

1

Ответ вы только позволяют доверять программное обеспечение для работы с администратора привилегии. Время от времени ПО НЕКОТОРЫХ ПОЛЬЗОВАТЕЛЕЙ должно обладать правами администратора и вносить чувствительные изменения в вашу систему. В противном случае у вас может быть только жесткий диск для чтения ...

0

Предполагая, что мы используем студии Installer-> Project Визуальная Setup - Вам нужен класс установки, как это внутри сборки, который производится установка, а затем убедитесь, что вы добавьте настраиваемое действие для «Первичного выхода» на этапе установки.

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(); 
     } 
    } 
}