Как запустить скрипт в WiX с настраиваемым действием - самый простой пример? - PullRequest
11 голосов
/ 04 октября 2008

Вопрос новичка WiX: Как мне
1. Скопируйте одноразовый скрипт оболочки в temp вместе с установщиком
например

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

2. Найдите и запустите этот скрипт в конце установки.
например

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

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

Я думаю, у меня есть как минимум три проблемы:

  • Я не могу найти permissions.cmd для его запуска - мне нужны [TEMPDIR] permissions.cmd или что-то еще?
  • My Sequence наступает слишком рано, до установки программы.
  • Мне нужно cmd / c permissions.cmd где-то здесь, вероятно, около ExeCommand ?

В этом примере permissions.cmd использует cacls.exe , чтобы добавить интерактивного пользователя с разрешениями на запись в % ProgramFiles% \ Vendor ACL. Я также мог бы использовать secureObject - этот вопрос «Как добавить интерактивного пользователя в каталог в локализованной Windows»?

Ответы [ 5 ]

5 голосов
/ 06 января 2009

Вот рабочий пример (для настройки разрешений, а не для запуска скрипта):

<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>

Обратите внимание, что в теге Permission используется Extended = "Yes", поэтому он использует таблицу SecureObjects и пользовательское действие, а не таблицу LockPermissions (см. Документы WiX для элемента Permission ). В этом примере разрешения, применяемые к каталогу MyProd SecureObjects, наследуются подкаталогами, что не относится к случаям использования LockPermissions.

4 голосов
/ 04 октября 2008

Я нашел сообщение в блоге От MSI до WiX, часть 5 - Пользовательские действия: Введение полезно, когда я хотел понять CustomActions в WiX.

Вы также можете найти определение CustomAction и его атрибуты в Элемент CustomAction .

Вам нужно сделать что-то вроде этого

<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>
2 голосов
/ 14 октября 2008

У вас есть пример того, как это используется? Я имею в виду, используйте ли CreateFolder вложенный в каталог, ACL которого я хочу изменить? Или я сначала использую CreateFolder , отдельно? Следующее даже близко?

<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
<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>

2 голосов
/ 14 октября 2008

Вместо выполнения настраиваемого действия вы можете попробовать использовать Элемент разрешения в качестве дочернего элемента элемента CreateFolder, например ::

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

Перезаписывает ли это или просто редактирует ACL папки?

Согласно документации MSDN она перезаписывает:

Каждый файл, раздел реестра или каталог, указанный в таблице LockPermissions, получает явный дескриптор безопасности, независимо от того, заменяет ли он существующий объект или нет.

Я только что подтвердил это, запустив тестовую установку в Windows 2000.

1 голос
/ 23 октября 2008

Большинство людей склонны избегать таблицы lockPermissions, поскольку она не является аддитивной, то есть она перезапишет ваши текущие разрешения (с точки зрения управляемой среды это плохо). Я бы предложил вам использовать инструмент, поддерживающий наследование ACL , такой как SUBINACL или SETACL, или один из многих инструментов ACL.

В связи с тем, что ваши предыдущие посты провалились, есть несколько причин. Есть четыре места, где вы можете поместить свои пользовательские действия (CA): пользовательский интерфейс, немедленный, отложенный и фиксировать / откат.

Вам необходим ваш ЦС для установки разрешений в отложенной последовательности, поскольку файлы отсутствуют до середины отложенной последовательности. Таким образом, все предшествующее потерпит неудачу.

  1. Ваша установка выполняется немедленно (поэтому не удастся)
  2. Ваша настройка в последовательности 1 (которую невозможно отложить, поэтому произойдет сбой)

Вам необходимо добавить атрибут Execute="Deferred" и изменить последовательность с «1» на:

<Custom Action="CallCmd" Execute="Deferred" Before="InstallFinalize" />

Это будет гарантировать, что это будет сделано после установки файлов, но до окончания отложенной фазы (нужное место).

Я бы также предложил вам вызывать EXE-файл напрямую, а не из пакетного файла. Запустится служба установки и файл EXE прямо в нужном вам контексте. Использование командного файла запустит командный файл в правильном контексте и потенциально потеряет контекст для нежелательной учетной записи во время выполнения.

...