views:

5473

answers:

5

Newbie WiX question: How do I
1. Copy a single-use shell script to temp along with the installer
e.g.

  <Binary Id='permissions.cmd' src='permissions.cmd'/>

2. Find and run that script at the end of the install.
e.g.

<CustomAction Id='SetFolderPermissions' BinaryKey='permissions.cmd' 
    ExeCommand='permissions.cmd' Return='ignore'/>  

<InstallExecuteSequence>
    <Custom Action="SetFolderPermissions" Sequence='1'/>
</InstallExecuteSequence>

I think I have at least three problems:

  • I can't find permissions.cmd to run it - do I need [TEMPDIR]permissions.cmd or something?
  • My Sequence comes too soon, before the program is installed.
  • I need cmd /c permissions.cmd somewhere in here, probably near ExeCommand?

In this example permissions.cmd uses cacls.exe to add the interactive user with write permissions to the %ProgramFiles%\Vendor ACL. I could also use secureObject - that question is "How do I add the interactive user to a directory in a localized Windows"?

+3  A: 

I found this link helpfull when I wanted to understand CA in wix here

You can also find the definition of CustomAction and it's attributs Here

You need to do something like this

    <CustomAction Id="CallCmd" Value="[SystemFolder]cmd.exe" />
    <CustomAction Id="RunCmd"  ExeCommand="/c permission.cmd" />
    <InstallExecuteSequence>
      <Custom Action="CallCmd" After="InstallInitialize" />
      <Custom Action="RunCmd" After="CallCmd" />
    </InstallExecuteSequence>
CheGueVerra
+2  A: 

Rather than running custom action you can try using Permission element as a child of CreateFolder element, e.g.:

<CreateFolder>
  <Permission User='INTERACTIVE' GenericRead='yes' GenericWrite='yes' 
              GenericExecute='yes' Delete='yes' DeleteChild='yes' />
  <Permission User='Administrators' GenericAll='yes' />
</CreateFolder>

Does this overwrite or just edit the ACL of the folder?

According to MSDN documentation it overwrites:

Every file, registry key, or directory that is listed in the LockPermissions Table receives an explicit security descriptor, whether it replaces an existing object or not.

I just confirmed that by running test installation on Windows 2000.

Pavel Chuchuva
Does this overwrite or just edit the ACL of the folder?
nray
+1  A: 

Have you got an example of how this is used? I mean, do use CreateFolder nested under the directory whose ACL I want to change? Or do I use CreateFolder first, separately? Is the following even close?

<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi"&gt;
<Fragment>
  <DirectoryRef Id="TARGETDIR">
    <Directory Id='ProgramFilesFolder' Name='PFiles'>
      <Directory Id="directory0" Name="MyApp" LongName="My Application">
        <Component Id="component0" DiskId="1" Guid="AABBCCDD-EEFF-1122-3344-556677889900">

          <CreateFolder>
            <Permission User='INTERACTIVE' 
              GenericRead='yes' 
              GenericWrite='yes' 
              GenericExecute='yes' 
              Delete='yes' 
              DeleteChild='yes' />
            <Permission User='Administrators' GenericAll='yes' />
          </CreateFolder>

          <File Id="file0" Name="myapp.exe" Vital="yes" Source="myapp.exe">
            <Shortcut Id="StartMenuIcon" Directory="ProgramMenuFolder" Name="MyApp" LongName="My Application" />
          </File>
        </Component>
      <Directory Id="directory1" Name="SubDir" LongName="Sub Directory 1">
        <Component Id="component1" DiskId="1" Guid="A9B4D6FD-B67A-40b1-B518-A39F1D145FF8">
          etc...
          etc...
          etc...
        </Component>
      </Directory>
    </Directory>
  </DirectoryRef>
</Fragment>

nray
Your example looks right. CreateFolder element is child of Component element which in turn is child of Directory element. Permissions will be set to this directory.
Pavel Chuchuva
+1  A: 

most people tend to steer clear of the lockPermissions table as it is not additive.

meaning it will overwrite your current permissions. (from a managed environment perspective this is bad).

I would suggest you use a tool which supports ACL inheritance such as SUBINACL or SETACL or one of the many ACL tools.

In relation to why your earlier posts failed there is a few reasons.

There are 4 loctions where you can put your CA's

UI, Immediate, Deferred, Commit/Rollback

You need your CA to set perms in the deferred sequence because the files are not present until midway through the deferred sequence. As such anything prior will fail.

1) your setup is in immediate (so will fail) 2) your setup is at sequence of 1 (which is not possible to be deferred so will fail)

You need to add an attribute of Execute="Deferred" and change sequence from "1" to

This will ensure its done after the files are installed but prior to the end of the deferred phase. (the desired location).

I would also suggest you call the EXE direct and not from a batch file. The installer service will launch and EXE direct in the context you need. Using a batch file will launch the batch file in correct context and potentially lose context to an undesired account whilst in execution.

hope this helps.

+2  A: 

Here's a working example (for setting permissions, not for running a script):

<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="ProgramFilesFolder" Name="PFiles">
    <Directory Id="BaseDir" Name="MyCo">
      <Directory Id="INSTALLDIR" Name="MyApp" LongName="MyProd">

        <!-- Create the folder, so that ACLs can be set to NetworkService -->
        <Component Id="TheDestFolder" Guid="{333374B0-FFFF-4F9F-8CB1-D9737F658D51}"
                   DiskId="1"  KeyPath="yes">
          <CreateFolder Directory="INSTALLDIR">
            <Permission User="NetworkService"
                        Extended="yes"
                        Delete="yes"
                        GenericAll="yes">
            </Permission>
          </CreateFolder>
        </Component>

      </Directory>
    </Directory>
  </Directory>
</Directory>

Note that this is using 'Extended="Yes"' in the Permission tag, so it's using the SecureObjects table and custom action not the LockPermissions table (see WiX docs for Permission Element). In this example the permissions applied to the MyProd directory by SecureObjects are inherited by subdirectories, which is not the case when LockPermissions is used.

Cool, I didn't know that .. thanks +1 ;)
CheGueVerra