2010-02-14 229 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