Как запустить script в WiX с помощью специального действия - самый простой пример?

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

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

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

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

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

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

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

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

Ответ 1

Вот рабочий пример (для установки разрешений, а не для запуска 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>

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

Ответ 2

Я нашел сообщение в блоге От 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>

Ответ 3

Вместо запуска настраиваемого действия вы можете попытаться использовать элемент разрешения в качестве дочернего элемента 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.

Ответ 4

Есть ли у вас пример того, как это используется? Я имею в виду, что использовать 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>

Ответ 5

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

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

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

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

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

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

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

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