我有一個通過ClickOnce安裝和更新的應用程序。應用程序通過FTP下載文件,因此需要添加爲Windows防火牆的例外。由於ClickOnce的工作方式,EXE的路徑隨着每次更新而改變,因此異常也需要更改。對防火牆進行更改的最佳方法是什麼?以便對最終用戶隱形?以編程方式將應用程序添加到Windows防火牆
(應用程序是用C#)
我有一個通過ClickOnce安裝和更新的應用程序。應用程序通過FTP下載文件,因此需要添加爲Windows防火牆的例外。由於ClickOnce的工作方式,EXE的路徑隨着每次更新而改變,因此異常也需要更改。對防火牆進行更改的最佳方法是什麼?以便對最終用戶隱形?以編程方式將應用程序添加到Windows防火牆
(應用程序是用C#)
我發現這篇文章,它有一個完整的包裝類包括操作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沙箱沒有出現任何問題。
不知道這是最好的方式,但運行netsh應該工作:
netsh防火牆添加allowedprogram C:\ MyApp的\ MyApp.exe的MyApp的ENABLE
我覺得這需要管理員權限不過,出於顯而易見的原因:)
編輯:我對ClickOnce知之甚少,不知道是否可以通過它運行外部程序。
我個人喜歡這個解決方案。調用這樣的外部過程要比使用Windows API更容易,尤其是在使用Qt/C++之類的情況下。 – jocull 2010-10-12 01:55:12
這取決於操作系統,不適用於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
剛剛添加,爲了完整起見,ClickOnce部署不限制應用程序在安裝後可以執行的操作,儘管它可以嘗試在啓動時檢查更新。 – Basic 2014-10-08 01:37:04
可以從防火牆訪問數據,查看以下文章。
真正的問題是做ClickOnce的沙箱允許這種訪問?我的猜測是,它不會。也許你可以使用web服務? (有關ClickOnce的數據訪問方法的更多信息,請參見Accessing Local and Remote Data in ClickOnce Applications)
如果在vs2010上添加引用hnetcfg時遇到任何問題,請檢查此鏈接http://connect.microsoft.com/VisualStudio/feedback/details/575401/interop-netfwtypelib-dll-change – Alexandre 2011-08-08 13:50:17
我得到一個拒絕訪問異常,在這裏提到http://stackoverflow.com/questions/8605710/get-my-application-to-be-allowed-access-through-firewall-using-c-sharp – PUG 2011-12-22 16:06:37
的死鏈接到「添加到Windows防火牆的例外列表中的應用」,可以在自由之路機發現:
答案是你只允許受信任的軟件與管理運行特權。有時軟件必須具有管理員權限並對系統進行敏感更改。你可能還有一個只讀的硬盤,否則...
這個答案可能會遲到。這是我最終使用:
假設我們使用了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();
}
}
}
我有同樣的問題,但與其他安全軟件(不只是Windows防火牆) – Jamiegs 2011-06-21 19:53:38