Pregunta

Tengo una aplicación que se instala y actualiza a través de ClickOnce.La aplicación se descarga de archivos a través de FTP, y por lo tanto necesita ser agregado como una excepción al firewall de windows.Debido a la forma en que ClickOnce obras, la ruta de acceso al ejecutable cambios con cada actualización, por lo que la excepción debe cambiar también.¿Cuál sería la mejor manera de tener los cambios realizados en el firewall de manera que la invisible para el usuario final?

(La aplicación está escrita en C#)

¿Fue útil?

Solución 2

He encontrado este artículo, que cuenta con una completa clase de contenedor incluido para manipular el firewall de windows. Agregar una Aplicación a la lista de excepciones del Firewall de Windows

/// 

/// 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)
    { }
}

El ClickOnce sandbox no presenta ningún problema.

Otros consejos

No estoy seguro si esta es la mejor manera, pero la ejecución de netsh debería funcionar:

netsh firewall add allowedprogram C:\MyApp\MyApp.exe MyApp HABILITAR

Creo que esto requiere Permisos de Administrador,aunque, por razones obvias :)

Editar:Yo no sé lo suficiente acerca de ClickOnce para saber si puede o no puede ejecutar programas externos a través de ella.

Es posible acceder a los datos desde el servidor de seguridad, mirar en los artículos siguientes.

La verdadera pregunta es ¿el ClickOnce sandbox permite este tipo de acceso?Mi conjetura sería que no.Tal vez usted podría utilizar un webservice?(Para obtener más información acerca de los métodos de acceso a datos en ClickOnce ver El acceso Local y Remoto de Datos en las Aplicaciones ClickOnce)

Los muertos enlace a "Agregar una Aplicación a la lista de excepciones de Firewall de Windows" se puede encontrar en La Wayback Machine:

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

La manera más fácil sé que sería el uso de netsh, usted puede simplemente eliminar la regla y volver a crear o configurar una regla de puerto, si el tuyo es fijo.
Aquí es una página que describe las opciones de su contexto de firewall.

Suponiendo que estamos usando un Instalador de Visual Studio->Configuración del Proyecto - Usted necesita un instalador de clase como esta dentro de un ensamblado que está instalado y, a continuación, asegúrese de añadir una acción personalizada para la "salida Principal" en la fase de instalación.

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

La respuesta es que sólo permite el software de confianza para que se ejecute con privilegios de Administrador.De vez en cuando ALGUNOS software tiene que tener privilegios de administrador y hacer sensibles a los cambios en el sistema.Usted podría tener una lectura de disco duro de sólo de lo contrario...

Esta respuesta podría ser tarde.Esto es lo que terminé usando:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top