18

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

我想授予用户组对程序文件下文件夹的系统和读取和执行权限的完全权限。不多也不少。

我知道有 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 元素放在 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。

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

4

5 回答 5

10

我遇到了同样的问题,并与 Rob M 讨论过。我打算做 Christian G 的回答(https://stackoverflow.com/a/5296967/18475),但 Rob 建议使用 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

于 2013-08-03T23:32:46.243 回答
7

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

<CreateFolder>
      <Permission User="Everyone" GenericAll="yes" ChangePermission="yes"/>
</CreateFolder>
于 2012-06-21T15:09:19.153 回答
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定义要翻译的属性:

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

于 2011-03-14T09:46:13.740 回答
1

由于 <Permission> 元素清除父文件夹的权限继承,您可以尝试为用户“Everyone”或“Administrators”使用单个 <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 显式设置权限,因为这些权限是由安装程序自动添加的。

于 2011-06-24T11:14:02.010 回答
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 访问会话属性

于 2010-02-16T11:50:34.290 回答