WIX: 给文件夹授权

20

我已经阅读了所有相关的帖子,但没有找到解决我的问题的完整答案。

我想将一个Program Files文件夹下的SYSTEM用户赋予完全权限,并将Users组的读取和执行权限授予该文件夹。仅此而已,不多也不少。

我知道使用WIX有三种方法可以给文件夹授权,但对我来说都不是很好,我会解释原因:

1)普通的Permission元素:

    <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权限扩展:

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

我将很高兴获得任何解决方案,包括使用自定义操作的解决方案...

5个回答

12

我遇到了完全相同的问题,与Rob M讨论过。我本来想采用Christian G的答案(https://dev59.com/TnE95IYBdhLWcg3wkekf#5296967),但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版本,此功能可能不被完全支持。如果无法使用,请尝试其他选项来翻译SIDs


这对我不起作用。[WIX_ACCOUNT_USERS] 将被解析为“BUILTIN\Users”,并授予名为“BUILTIN”的用户权限。 - Papa Mufflon
感谢您的跟进!我们最终撤销了这个操作。 - ferventcoder
1
就我所知,我们选择了实际的SIDs。更加确定性。 - ferventcoder
将SID插入到User-value中而不是用户或组名字并没有起作用,出现了错误。 我试图取消我的反对票,但在答案被编辑之前我无法取消:/ - Papa Mufflon
啊,我明白了 - 我相信传递SIDs需要不同的东西。我们不需要使用SIDs,因为我们使用的帐户是本地化的,而不是所有的帐户都是这样的 - 如果您查看此帖子(滚动到已接受的答案之后),您将看到翻译SID:https://social.msdn.microsoft.com/Forums/vstudio/en-US/39d9e905-2b35-4ce9-a544-4564f6b5a376/setting-file-permissions-in-languages-other-than-english-windows-installer-wix?forum=vssetup - ferventcoder
显示剩余3条评论

8
使用以下代码即可在不使用自定义操作的情况下完成此操作。我已经验证过这个方法可以工作(也适用于子文件夹)。另外,User Everyone 在本地化的 Windows 操作系统上已经映射好了。
<CreateFolder>
      <Permission User="Everyone" GenericAll="yes" ChangePermission="yes"/>
</CreateFolder>

1
这将不能在非美国英语环境中工作,因为“Everyone”必须进行本地化。 - John
我没有收到任何问题报告,而且我们部署到所有文化环境中。你是如何解决这个问题的? - Blake Niemyjski

3
另一种选择是使用简单的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" />

创建一个 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。
 <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元素。

2

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


2

由于< 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明确设置权限,因为这些权限会由安装程序自动添加。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接