WiX Cookbook
上QQ阅读APP看书,第一时间看更新

Changing the permissions on a folder for a user

When you set permissions on a folder, all of the files that are created within that folder after that point will inherit those permissions. This accommodates the Windows Installer's sequence, which as luck would have it, creates folders first and then adds files to them. This means we can set permissions once and let them trickle down. In this recipe, we'll give a user named Joe full access to a folder.

Getting ready

To prepare for this recipe, perform the following steps:

  1. Create a new setup project and name it FolderPermissionsInstaller.
  2. Add a text file named Sample.txt to the project. After installation, we can verify that the permissions that were set on the folder propagated to this file. Add a Component element to include it in the installation:
    <ComponentGroup Id="ProductComponents"  
                    Directory="INSTALLFOLDER">
      <Component Id="cmpSampleTXT" 
                 Guid="{79972677-2109-471C-A8FE-58A255CE43E3}">
        <File Source="Sample.txt" />
      </Component>
    </ComponentGroup>
  3. The user for whom we are setting permissions must already exist. Manually, create a user named Joe on the target computer by right-clicking on This PC and going to Manage | Local Users and Groups. Right-click on the Users node and select New User. Set the user's name as Joe as shown here:
    Getting ready

How to do it…

Place util:PermissionEx inside a CreateFolder element to set permissions on a folder. The following steps will show you how to do it:

  1. Reference UtilExtension by right-clicking on the References node in Solution Explorer, going to Add Reference… | Browse, and then adding WixUtilExtension.dll.
  2. Add the UtilExtension namespace to the Wix element in Product.wxs:
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" 
    xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  3. Within the ComponentGroup that's set to be installed to our installation directory, add a Component that has a child element CreateFolder:
    <ComponentGroup Id="ProductComponents" 
                    Directory="INSTALLFOLDER">
      <Component Id="cmpEmptyFolder" 
                 Guid="{292A233A-9C0E-479F-B83B-509F841B32D3}">
        <CreateFolder>
        </CreateFolder>
      </Component>
    </ComponentGroup>
  4. Add a util:PermissionEx element inside the CreateFolder element and set the name of the user we're giving access to, and the type of permissions to allow. The following code grants full access to the folder and the files it contains:
    <CreateFolder>
      <util:PermissionEx User="Joe" GenericAll="yes" />
    </CreateFolder>

How it works…

The PermissionEx element is stored in an assembly called WixUtilExtension.dll that we must reference before we can use it. To make things easy, the Add Reference… window takes us directly to the WiX bin folder where that file can be found. The second step is to add the UtilExtension XML namespace to our Product.wxs file. To do so, we added xmlns:util followed by the UtilExtension namespace, http://schemas.microsoft.com/wix/UtilExtension, to our Wix element. Afterwards, any element from WixUtilExtension.dll can be accessed by prefixing it with util.

By placing PermissionEx inside a CreateFolder element, which in turn is inside a Component element, we're instructing WiX to update the permissions on the directory that the component is being installed to. We can also use the CreateFolder element's Directory attribute to identify a directory to set permissions on. In that case, the folder that the component is being installed to doesn't matter.

The first attribute that we added to PermissionEx, User, identifies the user that our installer will grant folder permissions to. This user must either already exist on the target computer or be created by the installer. Otherwise, the installation will fail.

The second attribute, GenericAll, gives the user read, write, and execute permissions on the folder. Alternatively, we can specify each one individually with the GenericRead, GenericWrite, and GenericExecute attributes. More information about the PermissionEx element can be found at http://wixtoolset.org/documentation/manual/v3/xsd/util/permissionex.html and information about how Windows treats the different permissions available on MSDN at http://msdn.microsoft.com/en-us/library/bb727008.aspx.

Note

Although GenericAll, GenericWrite, and GenericExecute can be set alone, GenericRead can't be the only permission. You can, however, pair it with the Read attribute to give the user read-only access.

There's more…

There's another element, also called PermissionEx, that's included in the core WiX toolset and is not part of UtilExtension. It only has two attributes: Id and Sddl. It allows you to set the permissions on a file or folder using Security Descriptor Definition Language (SDDL). Because it's more complex and the UtilExtension's version of PermissionEx will suit most of your needs, I recommend that you only use this specialized element if your use case demands a more fine-tuned approach. It will only work where Windows Installer 5.0 is installed, which includes Windows 7 and newer operating systems.

There's also a Permission element in the core toolset that has many of the same attributes as util:PermissionEx. However, while PermissionEx will keep any existing ACLs on the folder, Permission wipes them all out and applies only those that you've explicitly set.