2010-02-14 228 views
16

我已阅读所有相关主题,但未找到我的问题的完整答案。WIX:将权限授予文件夹

我想授予SYSTEM的完全权限,并且阅读&将用户组的执行权限授予Program Files下的文件夹。没有更多,没有更多。

我知道有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试了一下。除此之外,我需要的权限元素放置在测试目录中的每个文件下(但如果这是唯一的情况下,我会管理)

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。

我会很高兴得到任何的解决方案,包括自定义操作解决方案...

回答

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

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

在维克斯定义使用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> 

最后,安排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

由于<权限>元素清除权限的继承自父文件夹,你可以尝试使用一个<权限>元素为用户“所有人”或“管理员”,然后< 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

这对于非美国英语区域设置不起作用,因为必须对“每个人”进行本地化。 – John 2015-11-18 16:09:29

+0

我没有报告任何问题,我们部署到所有文化。你怎么修好它的? – 2015-11-18 19:55:24

6

我有这个完全相同的问题,并与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

+0

被警告,我认为我们需要退出这个出于某种原因。 – ferventcoder 2014-05-28 12:57:17

+0

这不适合我。[WIX_ACCOUNT_USERS]将被解析为“BUILTIN \ Users”并将权限授予名为“BUILTIN”的用户。 – 2015-07-31 09:53:32

+0

只有在合并模块中设置权限,上述行为才是真实的!在WiX项目中使用[WIX_ACCOUNT_USERS]而不在WiX合并模块中正确设置用户组的权限。 – 2015-07-31 13:06:18