Подтвердить что ты не робот

WIX: предоставление разрешений в папку

Я прочитал все связанные темы и не нашел полного ответа на мою проблему.

Я хотел бы предоставить полные разрешения для системных и Read и Execute разрешений для группы пользователей в папку в Program Files. Ничего больше, не меньше.

Я знаю, что есть 3 способа предоставить разрешения для папки с помощью WIX, ни один из них не очень хорош для меня, и я объясню, почему:

1) Обычный элемент разрешений:

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

Проблема: Он не работает на внешней ОС, так как он не знает ключевое слово "Пользователи". Я попробовал это с SID. Кроме того, мне нужно разместить элемент Permission под каждым файлом в тестовом каталоге (но если это был единственный случай, я бы справился)

2) Элемент VixUtilsExtension 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>

Проблема: В папке также сохраняются разрешения по умолчанию для папки Program Files. Я не могу этого допускать.

3) PermissionEx с Sddl:

Проблема: Этот элемент доступен только при установке с MSI 5.0. Я использую installer 3.01.

Я буду рад получить любое решение, включая решения с пользовательскими действиями...

4b9b3361

Ответ 1

Используйте следующий код, чтобы выполнить это без специального действия. Я проверил это (также в дочерних папках). Также Пользователь всех отображается в локализованных операционных системах Windows.

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

Ответ 2

У меня была такая же проблема и поговорил с Робом М об этом. Я собирался сделать ответ Christian G (fooobar.com/questions/317428/...), но Роб предложил использовать WixQueryOsWellKnownSID (http://wix.sourceforge.net/manual-wix3/osinfo.htm), чтобы обойти не-американские локали.

В файле .wxs вы добавляете следующее:

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

И далее в файле .wxs, где вы хотите применить разрешения, это примерно так:

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

Теперь, когда вы запускаете свет, вам просто нужно связать WixUtilExtension.

light -ext WiXUtilExtension ...

ПРИМЕЧАНИЕ.. В зависимости от вашей версии WiX это может быть не полностью поддержано. Если это не сработает для вас, могут быть другие варианты, которые вы можете использовать для переводить SID.

Ответ 3

Другой вариант - иметь простой CA, который просто переводит свойство msi, которое содержит SID, в фактическое имя группы из локализованной ОС. CA не нужно откладывать, и он не выполняет фактическую работу по настройке разрешений.

Ниже приведен пример CA, который считывает значение свойства PROIty_TO_BE_TRANSLATED msi и переводит свойство msi, указанное им. Таким образом, вы можете запустить CA для перевода различных свойств 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;
  }

В WiX вы определяете свойства, которые нужно перевести, используя SID для учетных записей:

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

Создайте CA, который установит свойство PROPERTY_TO_BE_TRANSLATED, а затем вызовет CA, выполняющий перевод:

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

Не забудьте использовать свойства msi при настройке разрешений:

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

Наконец, планируйте CA перед 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>

Таким образом, CA выполняет только простую работу, оставляя настройку полномочий для элемента WiX.

Ответ 4

вам нужно реализовать отложенные пользовательские действия для изменения разрешений. Пример пользовательского действия С#:

[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;
}

вы можете переносить это на С++, пользовательское действие должно быть отложено - чем вы должны получить доступ к своим свойствам сеанса с помощью CustomActionData​​p >

Ответ 5

Как < Разрешение > элемент очищает наследование разрешений от родительских папок, вы можете попробовать использовать одиночный <Permission> элемент для пользователей "Все" или "Администраторы", за которыми следует < util: PermissionEx > элементы для установки разрешений для имен пользователей, которые не поддерживаются параметром <Permission> элемент, например:

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

Не требуется явно устанавливать разрешения для SYSTEM, так как они автоматически добавляются установщиком.