2010-02-14 29 views
16

He leído todos los temas relacionados y no he encontrado una respuesta completa a mi problema.WIX: dando permisos a una carpeta

Me gustaría dar permisos completos a SYSTEM y leer & Ejecutar permisos para el grupo de usuarios a una carpeta en Archivos de programa. Nada más y nada menos.

Sé que hay 3 formas de dar permisos a una carpeta utilizando WIX, ninguno de ellos es realmente bueno para mí y voy a explicar por qué:

1) elemento permiso regular:

<CreateFolder Directory="Test"> 
     <Permission User="SYSTEM" GenericAll="yes"/> 
     <Permission User="Users" Domain="[LOCAL_MACHINE_NAME]" 
     GenericRead="yes" Read="yes" GenericExecute="yes" ChangePermission="yes"/> 
    </CreateFolder> 

Problema: No funciona en el sistema operativo externo ya que no conoce la palabra clave "Usuarios". Lo intenté con SID también. Además de que tengo que colocar el elemento permiso debajo de cada archivo en el directorio de prueba (pero si éste era el único caso, habría conseguido)

elemento

2) WixUtilsExtension PermissionEx:

<CreateFolder Directory="Test"> 
     <util:PermissionEx User="SYSTEM" GenericAll="yes"/> 
     <util:PermissionEx User="Users" Domain="[LOCAL_MACHINE_NAME]" 
     GenericRead="yes" Read="yes" GenericExecute="yes" ChangePermission="yes"/> 
    </CreateFolder> 

Problema: La carpeta también conserva los permisos predeterminados de la carpeta Archivos de programa. No puedo permitir eso.

3) PermissionEx con SDDL:

Problema: Este elemento sólo está disponible cuando se instala con MSI 5.0. Estoy usando el instalador 3.01.

estaré feliz de conseguir cualquier solución, incluyendo soluciones con acciones personalizadas ...

Respuesta

1

es necesario implementar acciones personalizadas diferida para cambiar los permisos. C# encargo acción ejemplo:

[CustomAction] 
public static ActionResult SetFolderPermission(Session session) 
{ 
    string folder = session.CustomActionData["Folder"].Trim('\"'); 
    string sid = session.CustomActionData["SID"].Trim('\"'); 
    System.Security.Principal.SecurityIdentifier sidID = new System.Security.Principal.SecurityIdentifier(sid); 

    System.Security.AccessControl.DirectorySecurity ds = System.IO.Directory.GetAccessControl(folder); 
    ds.AddAccessRule(new System.Security.AccessControl.FileSystemAccessRule(sidID 
       , System.Security.AccessControl.FileSystemRights.Write 
       , System.Security.AccessControl.InheritanceFlags.ObjectInherit 
       , System.Security.AccessControl.PropagationFlags.NoPropagateInherit 
       , System.Security.AccessControl.AccessControlType.Allow)); 
    System.IO.Directory.SetAccessControl(folder , ds); 

    return ActionResult.Success; 
} 

es posible que el puerto que en C++, acción personalizada debe ser diferida - que debe acceder a sus propiedades de sesión por CustomActionData

2

Otra opción sería tener una CA simple que simplemente traducir una propiedad msi que contiene el SID al nombre real del grupo del sistema operativo localizado. La CA no tiene que diferirse y no está haciendo el trabajo real de establecer los permisos.

A continuación se muestra un ejemplo de CA que lee el valor de PROPERTY_TO_BE_TRANSLATED propiedad msi y traduce la propiedad msi indicada por él. De esta forma, puede ejecutar la CA para traducir diferentes propiedades de msi.

[CustomAction] 
    public static ActionResult TranslateSidToName(Session session) 
    { 
    var property = session["PROPERTY_TO_BE_TRANSLATED"]; 
    if (String.IsNullOrEmpty(property)) 
    { 
     session.Log("The {0} property that should say what property to translate is empty", translateSidProperty); 
     return ActionResult.Failure; 
    } 
    var sid = session[property]; 
    if (String.IsNullOrEmpty(sid)) 
    { 
     session.Log("The {0} property that should contain the SID to translate is empty", property); 
     return ActionResult.Failure; 
    } 
    try 
    { 
     // convert the user sid to a domain\name 
     var account = new SecurityIdentifier(sid).Translate(typeof(NTAccount)).ToString(); 
     session[property] = account; 
     session.Log("The {0} property translated from {1} SID to {2}", property, sid, account); 
    } 
    catch (Exception e) 
    { 
     session.Log("Exception getting the name for the {0} sid. Message: {1}", sid, e.Message); 
     return ActionResult.Failure; 
    } 
    return ActionResult.Success; 
    } 

En WiX se definen las propiedades que se convierten utilizando los SID for the accounts:

<Property Id="AdminAccount" Value="S-1-5-32-544" /> 
    <Property Id="EveryoneAccount" Value="S-1-1-0" /> 

Crear la CA que se establezca la propiedad PROPERTY_TO_BE_TRANSLATED y luego llamar a la CA haciendo la traducción:

<CustomAction Id="TranslateAdmin_SetProperty" Property="PROPERTY_TO_BE_TRANSLATED" Value="AdminAccount"/> 
<CustomAction Id="TranslateAdmin" BinaryKey="CommonCustomActions" DllEntry="TranslateSidToName" Impersonate="no" /> 
<CustomAction Id="TranslateEveryone_SetProperty" Property="PROPERTY_TO_BE_TRANSLATED" Value="EveryoneAccount" /> 
<CustomAction Id="TranslateEveryone" BinaryKey="CommonCustomActions" DllEntry="TranslateSidToName" Impersonate="no" /> 

No olvide utilizar las propiedades msi al establecer los permisos:

<CreateFolder>     
    <Permission GenericAll="yes" User="[AdminAccount]" /> 
    <Permission GenericRead="yes" GenericExecute="yes" User="[EveryoneAccount]" /> 
</CreateFolder> 

Por último, programe la CA antes de CreateFolder

<InstallExecuteSequence> 
    <Custom Action='TranslateAdmin_SetProperty' Before='TranslateAdmin' /> 
    <Custom Action='TranslateAdmin' Before='CreateFolders' /> 
    <Custom Action='TranslateEveryone_SetProperty' Before='TranslateEveryone' /> 
    <Custom Action='TranslateEveryone' Before='CreateFolders' /> 
    </InstallExecuteSequence> 

De esta manera el CA está haciendo solamente un trabajo sencillo, dejando la configuración de permisos para el elemento de WiX.

1

A medida que el <Permiso> elemento borra la herencia de permisos de carpetas principales, se podría tratar de usar un solo <Permiso> elemento para los usuarios "Todos" o "Administradores", seguido de < util: PermissionEx > elementos para configurar los permisos de nombres de usuario que no están soportadas por el elemento <permiso>, por ejemplo:

<Permission User="Everyone" GenericRead="no" /> 
<util:PermissionEx User="Users" Domain="[LOCAL_MACHINE_NAME]" GenericRead="yes" Read="yes" GenericExecute="yes" ChangePermission="yes" /> 

no es necesario para establecer explícitamente el permiso para SISTEMA, ya que estos se añaden automáticamente por el instalador.

6

Utilice el siguiente código para lograr esto sin una acción personalizada. He verificado que esto funciona (también en carpetas secundarias). También el User Everyone está mapeado en sistemas operativos de Windows localizados.

<CreateFolder> 
     <Permission User="Everyone" GenericAll="yes" ChangePermission="yes"/> 
</CreateFolder> 
+1

Esto no funcionará para las configuraciones regionales que no sean de EE. UU., Ya que "Todos" debe estar localizado. – John

+0

No he tenido ningún problema informado y nos implementamos en todas las culturas. ¿Cómo lo arreglaste? –

6

Tuve este mismo problema y hablé con Rob M al respecto. Iba a responder la respuesta de Christian G (https://stackoverflow.com/a/5296967/18475), pero Rob sugirió usar WixQueryOsWellKnownSID (http://wix.sourceforge.net/manual-wix3/osinfo.htm) para desplazarse por las configuraciones regionales que no están en EE. UU.

En el archivo .wxs se agrega lo siguiente:

<PropertyRef Id="WIX_ACCOUNT_LOCALSYSTEM" /> 
<PropertyRef Id="WIX_ACCOUNT_USERS" /> 

Y más abajo en el archivo .wxs en la que desea aplicar los permisos Es como esto:

<Permission GenericAll="yes" User="[WIX_ACCOUNT_LOCALSYSTEM]" /> 
<Permission GenericRead="yes" GenericExecute="yes" User="[WIX_ACCOUNT_USERS]" /> 

Ahora cuando se ejecuta luz, solo necesitas vincular WixUtilExtension.

light -ext WiXUtilExtension ... 

NOTA: Dependiendo de la versión de WiX, esto puede no ser totalmente compatibles. Si no funciona para usted, puede haber otras opciones que puede usar para translate SIDs.

+0

Tenga cuidado, creo que teníamos que respaldar esto por alguna razón. – ferventcoder

+0

Esto no funciona para mí.[WIX_ACCOUNT_USERS] se resolverá para "BUILTIN \ Users" y otorga el permiso a un usuario llamado "BUILTIN". –

+0

¡El comportamiento antes mencionado solo es verdadero si establece los permisos en un módulo de fusión! El uso de [WIX_ACCOUNT_USERS] en un proyecto de WiX y no en un módulo de combinación de WiX configura correctamente los permisos para el grupo de usuarios. –

Cuestiones relacionadas