2008-09-22 43 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的ENABLE

我覺得這需要管理員權限不過,出於顯而易見的原因:)

編輯:我對ClickOnce知之甚少,不知道是否可以通過它運行外部程序。

+0

我個人喜歡這個解決方案。調用這樣的外部過程要比使用Windows API更容易,尤其是在使用Qt/C++之類的情況下。 – jocull 2010-10-12 01:55:12

+7

這取決於操作系統,不適用於Win7(已棄用)。你需要做一些更醜陋的事情,比如:netsh advfirewall firewall add rule name =「allow messenger」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的沙箱允許這種訪問?我的猜測是,它不會。也許你可以使用web服務? (有關ClickOnce的數據訪問方法的更多信息,請參見Accessing Local and Remote Data in ClickOnce Applications

+0

如果在vs2010上添加引用hnetcfg時遇到任何問題,請檢查此鏈接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 **是操作系統特定的。您無法在Server 2003和Server 2008上使用1個netsh命令。 – Achilles 2011-07-13 17:14:07

1

答案是你只允許受信任的軟件與管理運行特權。有時軟件必須具有管理員權限並對系統進行敏感更改。你可能還有一個只讀的硬盤,否則...

0

假設我們使用了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(); 
     } 
    } 
} 
相關問題