c# .net windows-installer file-permissions

c# - Cómo otorgar permisos de lectura/escritura a una carpeta durante la instalación usando.NET



windows-installer file-permissions (6)

Como se ha mencionado anteriormente, el grupo Usuarios no tiene permiso de escritura en Archivos de programa. Si no desea lidiar con la clase de instalador o Wix (si es un programa simple), simplemente prefiera instalar su software en un volumen de Windows.

Estoy hablando del asistente de instalación de Visual Studio : cambiar la propiedad de la carpeta de aplicación '' DefaultLocation '' de [ProgramFilesFolder] a [WindowsVolume] [Manufacturer] [ProductName] en File System en Target Machine.

Tengo un proyecto de instalación que he creado con Visual Studio 2010.

El instalador funciona bien en términos de instalar la aplicación y todas sus dependencias en sus subdirectorios y directorios de datos del programa.

Sin embargo, noté que cada directorio (la carpeta raíz y todos sus subdirectorios) que el instalador creó no otorga permisos de "Escritura". Los únicos permisos que se agregan a los directorios para el grupo "Usuarios" son:

  • Leer y ejecutar
  • Lista de contenidos en la carpeta
  • Leer

Esta, aparente configuración de permisos predeterminados, ocurrirá independientemente de si el usuario instala la aplicación como "Administrador" o no.

Me parece extraño que el instalador no dé permisos de "Escritura" a una carpeta que está utilizando la aplicación que se está instalando. Es aún más confuso que la carpeta que el instalador crea en la carpeta ProgramData para la base de datos de la aplicación. no obtiene permisos de "escritura".

Mi pregunta es, ¿hay una manera de configurar el proyecto de instalación de modo que si y cuando crea una carpeta, podamos decirle qué tipo de permisos le damos y a quién? En mi caso, necesito proporcionar el directorio raíz (de la aplicación) y todos sus subdirectorios, y la carpeta que se encuentra en la carpeta ProgramData "Permisos de lectura / escritura" para el "Grupo de usuarios". Técnicamente, estoy bien con dar los dirs "Control total" al "Grupo de usuarios".


De forma predeterminada, el grupo Usuarios no tiene acceso de escritura en ubicaciones por máquina como Archivos de programa. Este es un estándar de Windows que no está relacionado con las instalaciones. Sin embargo, durante la instalación puede establecer los permisos que desee.

Windows Installer admite permisos personalizados, pero Visual Studio no ofrece una forma de configurarlos. Así que la única solución en Visual Studio es una acción personalizada.

Desafortunadamente, Visual Studio no admite acciones personalizadas adjuntas. Por lo tanto, usar XCACLS.EXE para establecer permisos solo funcionaría si lo incluyes en tu paquete (se instalará en la máquina de destino junto con tus archivos).

Una solución más limpia, pero más compleja es escribir una acción personalizada usted mismo (usando un código personalizado) para establecer los permisos que desea.

La solución más rápida y limpia sería utilizar una herramienta de creación de configuración diferente que ofrezca más control sobre los permisos.


El comportamiento es por diseño. Los programas no deben modificarse ellos mismos (de ahí su directorio de instalación) para nada más que actualizaciones (lo que de nuevo se puede hacer con el instalador de Windows sin problemas). Si está utilizando .NET, el almacenamiento aislado es una excelente ubicación para almacenar datos de usuarios.


Supongo que mi otra publicación fue eliminada por ser un poco demasiado general, así que la he refinado a continuación:

Lo que hay que hacer es hacer una acción personalizada. Es bastante sencillo, consulte el tutorial de MSDN para escribir una acción personalizada de C # here . Pondrás tu código de cambio de permiso dentro del método de instalación:

Siga los primeros pasos del enlace para obtener un nuevo proyecto de instalador al que se haga referencia desde su solución de instalador. Tienes que hacerlo de esta manera, para que puedas construir una dll que se llame al final de la instalación.

En realidad, establecer los privilegios de lectura / escritura para los Usuarios fue un poco más complicado, y lo más cercano que pude hacer fue establecer para Usuarios Autenticados. Confundí algunas otras soluciones que encontré en Internet para llegar a esto:

public override void Install(IDictionary stateSaver) { // This gets the named parameters passed in from your custom action string folder = Context.Parameters["folder"]; // This gets the "Authenticated Users" group, no matter what it''s called SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null); // Create the rules FileSystemAccessRule writerule = new FileSystemAccessRule(sid, FileSystemRights.Write, AccessControlType.Allow); if (!string.IsNullOrEmpty(folder) && Directory.Exists(folder)) { // Get your file''s ACL DirectorySecurity fsecurity = Directory.GetAccessControl(folder); // Add the new rule to the ACL fsecurity.AddAccessRule(writerule); // Set the ACL back to the file Directory.SetAccessControl(folder, fsecurity); } // Explicitly call the overriden method to properly return control to the installer base.Install(stateSaver); }

Luego, cuando cree su acción personalizada, edite sus propiedades y agregue algo como esto en la propiedad CustomActionData:

/folder="[CommonAppDataFolder][ProductName]"


DirectoryInfo info = new DirectoryInfo(path[x]); DirectorySecurity security = info.GetAccessControl(); security.AddAccessRule(new FileSystemAccessRule(logonName, FileSystemRights.Modify, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow)); security.AddAccessRule(new FileSystemAccessRule(logonName, FileSystemRights.Modify, InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); info.SetAccessControl(security);

La configuración de la parte heredada también es importante si desea guardar y acceder a más de un archivo en la carpeta ProgramData.


private static void GrantAccess(string file) { bool exists = System.IO.Directory.Exists(file); if (!exists) { DirectoryInfo di = System.IO.Directory.CreateDirectory(file); Console.WriteLine("The Folder is created Sucessfully"); } else { Console.WriteLine("The Folder already exists"); } DirectoryInfo dInfo = new DirectoryInfo(file); DirectorySecurity dSecurity = dInfo.GetAccessControl(); dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow)); dInfo.SetAccessControl(dSecurity); }

El código anterior establecerá los derechos de acceso de la carpeta a control total / lectura-escritura para cada usuario (todos).