WIX: предоставление разрешений для папки - PullRequest
18 голосов
/ 14 февраля 2010

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

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

Я знаю, что есть 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>

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

2) WixUtilsExtension 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.Я использую установщик 3.01.

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

Ответы [ 5 ]

8 голосов
/ 04 августа 2013

У меня была точно такая же проблема, и я говорил об этом с Робом М. Я собирался ответить Кристианом Джи (https://stackoverflow.com/a/5296967/18475),, но Роб предложил использовать 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 .

7 голосов
/ 21 июня 2012

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

<CreateFolder>
      <Permission User="Everyone" GenericAll="yes" ChangePermission="yes"/>
</CreateFolder>
2 голосов
/ 14 марта 2011

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

Ниже приведен пример CA, который считывает значение свойства msi PROPERTY_TO_BE_TRANSLATED и транслирует указанное им свойство 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.

1 голос
/ 24 июня 2011

Поскольку элемент очищает наследование разрешений от родительских папок, вы можете попробовать использовать один элемент для пользователей «Все» или «Администраторы», а затем элементы для установки разрешений для пользователя. имена, которые не поддерживаются элементом , например:

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

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

1 голос
/ 16 февраля 2010

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

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

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

...