如何通过编程为DCOM Config添加用户并配置访问权限(基于WIX)
自定义DCOM访问权限:WIX集成 + 编程实现方案
我之前处理过类似的DCOM权限配置需求,WIX本身没有内置元素直接支持修改DCOM Config的权限,所以得靠自定义操作来实现;而编程添加用户到访问权限列表,用WMI或者Windows API都能搞定,下面分两部分给你详解:
一、在WIX安装程序中配置DCOM权限
要在WIX安装流程中自定义DCOM访问权限,核心是编写托管自定义操作(C#)——WMI操作在C#里更易处理,也能很好地集成到WIX的安装逻辑中:
1. 编写C#自定义操作代码
利用System.Management和System.Security.AccessControl命名空间,操作WMI的DCOM配置类,通过修改安全描述符添加用户权限。示例代码如下:
using System; using System.Management; using System.Security.AccessControl; using System.Security.Principal; using Microsoft.Deployment.WindowsInstaller; public class DcomPermissionActions { [CustomAction] public static ActionResult AddUserToDcomAccess(Session session) { try { // 替换为你的DCOM组件CLSID string targetClsid = "{YOUR-COMPONENT-CLSID-HERE}"; // 替换为要添加的用户(格式:DOMAIN\UserName 或 .\LocalUser) string userToAdd = "DOMAIN\\JohnDoe"; // 连接到本地WMI服务的DCOM应用设置类 var dcomClass = new ManagementClass("Win32_DCOMApplicationSetting"); var dcomInstances = dcomClass.GetInstances(); foreach (ManagementObject dcomObj in dcomInstances) { if (dcomObj["CLSID"].ToString().Equals(targetClsid, StringComparison.OrdinalIgnoreCase)) { // 获取当前的访问安全描述符 var getAccessParams = dcomObj.InvokeMethod("GetAccessSecurity", null, null); byte[] originalSd = getAccessParams["Descriptor"] as byte[]; // 解析安全描述符并添加用户权限 var sd = new RawSecurityDescriptor(originalSd, 0); var ntAccount = new NTAccount(userToAdd); var sid = ntAccount.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier; // 添加允许本地和远程访问的ACE(权限掩码:0x1=本地访问,0x2=远程访问) var ace = new CommonAce( AceFlags.None, AccessControlType.Allow, 0x1 | 0x2, sid, false, null); sd.DiscretionaryAcl.InsertAce(0, ace); // 转换回二进制安全描述符并设置回去 byte[] newSd = new byte[sd.BinaryLength]; sd.GetBinaryForm(newSd, 0); var setAccessParams = dcomObj.GetMethodParameters("SetAccessSecurity"); setAccessParams["Descriptor"] = newSd; dcomObj.InvokeMethod("SetAccessSecurity", setAccessParams, null); session.Log($"Successfully added user {userToAdd} to DCOM access permissions for CLSID {targetClsid}"); break; } } return ActionResult.Success; } catch (Exception ex) { session.Log($"Error modifying DCOM permissions: {ex.Message}\n{ex.StackTrace}"); return ActionResult.Failure; } } }
2. 集成到WIX项目
- 把编译好的C# DLL添加到WIX项目,定义
Binary元素:
<Binary Id="DcomPermissionCA" SourceFile="..\DcomPermissionCustomAction\bin\Release\DcomPermissionCustomAction.dll" />
- 注册自定义操作,修改系统权限需要管理员权限,所以设置
Execute="deferred"和Impersonate="no":
<CustomAction Id="AddUserToDcomAccess" BinaryKey="DcomPermissionCA" DllEntry="AddUserToDcomAccess" Execute="deferred" Impersonate="no" />
- 在安装序列中添加操作,确保在COM组件注册完成后执行(放在
InstallFinalize之前):
<InstallExecuteSequence> <Custom Action="AddUserToDcomAccess" After="InstallFinalize">NOT Installed</Custom> </InstallExecuteSequence>
二、独立编程添加用户到DCOM Config访问权限
如果是单独的程序(非WIX安装场景),同样可以复用上面的核心逻辑,或者用VBScript脚本做自动化:
C#独立程序版本
直接提取上面的核心逻辑,去掉WIX的Session相关代码,换成控制台日志即可:
// 省略命名空间和引用,核心逻辑和AddUserToDcomAccess方法一致 // 把session.Log替换为Console.WriteLine即可
VBScript版本(适合脚本自动化)
Const LOCAL_ACCESS = 1 Const REMOTE_ACCESS = 2 strTargetCLSID = "{YOUR-COMPONENT-CLSID}" strUser = "DOMAIN\JaneDoe" Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colDCOMApps = objWMIService.ExecQuery( _ "SELECT * FROM Win32_DCOMApplicationSetting WHERE CLSID = '" & strTargetCLSID & "'") For Each objDCOMApp In colDCOMApps ' 获取当前安全描述符 Set objOutParams = objDCOMApp.GetAccessSecurity() arrOriginalSD = objOutParams.Descriptor ' 注:VBScript处理安全描述符较繁琐,推荐调用C#控制台程序或使用ADSI方法修改 ' 此处假设已得到修改后的安全描述符数组arrModifiedSD Set objInParams = objDCOMApp.Methods_("SetAccessSecurity").InParameters.SpawnInstance_() objInParams.Descriptor = arrModifiedSD objDCOMApp.ExecMethod_ "SetAccessSecurity", objInParams WScript.Echo "Successfully added user " & strUser & " to DCOM access permissions" Next
重要注意事项
- 管理员权限:不管是WIX安装还是独立程序,都需要以管理员身份运行,否则没有修改DCOM权限的权限。
- CLSID准确性:必须使用目标DCOM组件的正确CLSID,可在注册表
HKCR\CLSID路径下找到对应组件的标识。 - 权限掩码:根据需求设置正确的权限掩码,除了本地/远程访问,还可添加
LAUNCH(0x4)或ACTIVATE(0x8)权限。
内容的提问来源于stack exchange,提问作者BassetMan
相关产品推荐
相关产品推荐

