2010-02-14 1 views
16

Я прочитал все связанные темы и не нашел полного ответа на мою проблему.WIX: Предоставление разрешений в папку

Я хотел бы предоставить полные разрешения для системы и читать & Выполнить права доступа к группе пользователей в папку в разделе «Файлы программы». Ни больше ни меньше.

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

1) Regular Разрешение элемент:

<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. Кроме этого мне нужно поместить элемент Разрешение под каждого файла в каталоге 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. Я использую installer 3.01.

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

ответ

1

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

[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

2

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

Ниже приведен образец ЦС, который считывает значение свойства PROI_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 for the accounts:

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

Создание центра сертификации, который установит свойство PROPERTY_TO_BE_TRANSLATED и затем вызвать СА делает перевод:

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

Наконец, график СА до того 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> 

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

1

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

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

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

6

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

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

Это не будет работать для локалей, отличных от US Eng, потому что «Everyone» должен быть локализован. – John

+0

У меня не было никаких проблем, и мы развертываем все культуры. Как ты это починил? –

6

У меня была такая же проблема и я поговорил с Робом М об этом. Я собирался сделать ответ Кристиана Г (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, это не может быть полностью поддерживается. Если это не сработает для вас, могут быть другие варианты, которые вы можете использовать для translate SIDs.

+0

Будьте осторожны, я думаю, нам нужно было это сделать по какой-то причине. – ferventcoder

+0

Это не работает для меня.[WIX_ACCOUNT_USERS] будет разрешено «BUILTIN \ Users» и предоставит разрешение пользователю под названием «BUILTIN». –

+0

Вышеупомянутое поведение действует только в том случае, если вы устанавливаете разрешения в модуле слияния! Использование [WIX_ACCOUNT_USERS] в проекте WiX, а не в модуле объединения WiX, правильно устанавливает права доступа для группы пользователей. –