如何通过 c# 以编程方式更改 COM 安全设置?

Posted

技术标签:

【中文标题】如何通过 c# 以编程方式更改 COM 安全设置?【英文标题】:How can I change COM Security settings programmatically by c#? 【发布时间】:2015-07-30 09:20:05 【问题描述】:

我需要使用 .NET 方法以编程方式更改 COM 安全权限。 我的意思是这些设置:

我该怎么做?谢谢!

【问题讨论】:

【参考方案1】:

据我所知,没有 API 可以做到这一点。不过COM和DCOM的访问控制都是在注册表中设置的,主要是在“隐身”OLE下(由于历史原因)。同时 .NET 有标准的类来操作注册表。

所以这是我在面对这个任务时应该做的:

启动注册表监视器,例如 Mark Russinovich 的 formerly SysInternals, now Microsoft

使用 Windows UI 以交互方式设置一些 COM 设置,并监控注册表更改。

可选但强烈推荐:在有一些非常有针对性的搜索关键字( 注册表项)尝试在 google 中获取文档/代码,或者更好的方法 在github中搜索代码

实现我的 C# 类,什么在操作适当的 注册表类

【讨论】:

这就是我成功的做法。我在这个答案中分享了代码:***.com/a/45478691/2135045 很高兴有人在实践中成功应用了该方法【参考方案2】:

我知道这个热带很旧,但这是我最终使用的解决方案,以防有人需要它。如上所述,我找不到任何 API 来执行此操作,必须直接在存储坐席的注册表项上工作。 应编辑填充键:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\DefaultAccessPermission HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\DefaultLaunchPermission

权限以二进制形式存储。 你可以试试我的代码:

static class ComACLRights

    public const int COM_RIGHTS_EXECUTE = 1;
    public const int COM_RIGHTS_EXECUTE_LOCAL = 2;
    public const int COM_RIGHTS_EXECUTE_REMOTE = 4;
    public const int COM_RIGHTS_ACTIVATE_LOCAL = 8;
    public const int COM_RIGHTS_ACTIVATE_REMOTE = 16;


static void Main(string[] args)

     SetCOMSercurityAccess("testuser", "DefaultAccessPermission");
     SetCOMSercurityAccess("testuser", "DefaultLaunchPermission");


private static void SetCOMSercurityAccess(string username, string regKey)

    //Get sid from username
    NTAccount f = new NTAccount(username);
    SecurityIdentifier sid = (SecurityIdentifier)f.Translate(typeof(SecurityIdentifier));

    //Read reg key responsible for COM Sercurity
    var accessKey = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Ole", regKey, null);

    RawSecurityDescriptor sd;

    if (accessKey == null)
    
        //Key does not exist
        sd = new RawSecurityDescriptor("");
    
    else
    
        //read security settings
        sd = new RawSecurityDescriptor(accessKey as byte[], 0);
    

    //Look fo input foruser
    var acl = sd.DiscretionaryAcl;
    var found = false;
    foreach (CommonAce ca in acl)
    
        if (ca.SecurityIdentifier == sid)
        
            //ensure local access is set
            ca.AccessMask |= ComACLRights.COM_RIGHTS_EXECUTE | ComACLRights.COM_RIGHTS_EXECUTE_LOCAL | ComACLRights.COM_RIGHTS_ACTIVATE_LOCAL;    //set local access.  Always set execute
            found = true;
            break;
        
    
    if (!found)
    
        CommonAce ca = new CommonAce(
            AceFlags.None,
            AceQualifier.AccessAllowed,
            ComACLRights.COM_RIGHTS_EXECUTE | ComACLRights.COM_RIGHTS_EXECUTE_LOCAL | ComACLRights.COM_RIGHTS_ACTIVATE_LOCAL,
                sid,
                false,
                null);
        acl.InsertAce(acl.Count, ca);
    
    //re-set the ACL
    sd.DiscretionaryAcl = acl;

    //Convert back to binary and save
    byte[] binaryform = new byte[sd.BinaryLength];
    sd.GetBinaryForm(binaryform, 0);
    Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Ole", regKey, binaryform, RegistryValueKind.Binary);

这段代码的灵感主要来自this answer

【讨论】:

以上是关于如何通过 c# 以编程方式更改 COM 安全设置?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式更改 WMI 的设置而不是使用 wmimgmt.msc snappin?

如何以编程方式更改 C# 中的程序集名称

以编程方式向 C# 中的文件添加安全权限

如何以编程方式更改我的 Windows 桌面墙纸?

如何使用 c# 以编程方式将证书安装到本地机器存储中?

asp.net C# 如何以编程方式更改 Page_Load 上的正文背景图像