WIX:授予文件夹权限

时间:2010-02-14 09:26:01

标签: permissions wix installer windows-installer wix-extension

我已阅读所有相关主题,但未找到问题的完整答案。

我想授予SYSTEM和Read& amp ;;对Users组执行权限到Program Files下的文件夹。没什么,没什么。

我知道有三种方法可以使用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)使用Sddl的PermissionEx:

问题:此元素仅在使用MSI 5.0安装时可用。我正在使用安装程序3.01。

我很乐意获得任何解决方案,包括采用自定义操作的解决方案......

5 个答案:

答案 0 :(得分:8)

我有同样的问题,并与Rob M讨论过这个问题。我打算做Christian G的答案(https://stackoverflow.com/a/5296967/18475),但Rob建议使用WixQueryOsWellKnownSID(http://wix.sourceforge.net/manual-wix3/osinfo.htm)来绕过非en-US语言环境。

.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

答案 1 :(得分:7)

使用以下代码无需自定义操作即可完成此操作。我已经验证了这个工作(也在子文件夹上)。此外,User Everyone映射在本地化的Windows操作系统上。

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

答案 2 :(得分:2)

另一种选择是拥有一个简单的CA,它只是将包含SID的msi属性转换为本地化操作系统中组的实际名称。 CA不必延迟,也不是在设置权限的实际工作。

以下是CA的示例,它读取PROPERTY_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属性的CA,然后调用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>

最后,在CreateFolder之前安排CA

 <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元素。

答案 3 :(得分:1)

您需要实施延迟自定义操作以更改权限。 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访问您的会话属性

答案 4 :(得分:1)

作为&lt;权限&gt; element清除父文件夹的权限继承,您可以尝试使用单个&lt; Permission&gt;用户“Everyone”或“Administrators”后跟&lt; util:PermissionEx&gt;的元素用于设置&lt; Permission&gt;不支持的用户名权限的元素元素,例如:

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

不需要显式设置SYSTEM权限,因为安装程序会自动添加这些权限。