通过.NET \ C#使用组策略对象(GPO)

时间:2013-12-23 06:12:01

标签: .net windows gpo

我想在GPO注册表项中添加注册表项吗?标准的.NET注册表类不处理这种情况。

1 个答案:

答案 0 :(得分:3)

我找到的工作解决方案是使用组策略对象COM + API接口。

说明:

  • 必须使用标记为STA的线程。它可以应用于整个应用程序或只应用于一个线程;

  • 必须通过ComInterop使用COM + IGroupPolicyObject;

  • MS鼓励在.NET中使用“GPMC类库”,但此库无法正常工作;

  • .NET端的IGroupPolicyObject代理必须包含COM对象中所有方法的定义(否则会抛出异常“尝试读取或写入受保护的内存。这通常表示其他内存已损坏“通过其中一种方法);

以下代码支持在GPO下管理(添加,删除等)注册表项:

static void Main(string[] args)
{
    Thread t = new Thread(new ThreadStart(StartNewStaThread));
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
}

private static void StartNewStaThread()
{
    GPClass gpClass = new GPClass();
    IGroupPolicyObject gpo = (IGroupPolicyObject)gpClass;

    uint hr = gpo.OpenLocalMachineGpo(1); // GPO_OPEN_LOAD_REGISTRY=0x00000001

    if (hr == 0) //S_OK == 0
    {
        StringBuilder sb = new StringBuilder();
        hr = gpo.GetDisplayName(sb, 50);
    }
}

[ComImport, Guid("EA502722-A23D-11d1-A7D3-0000F87571E3")]
public class GPClass
{
}

[ComImport, Guid("EA502723-A23D-11d1-A7D3-0000F87571E3"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IGroupPolicyObject
{
 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords")]
    uint New(
        [MarshalAs(UnmanagedType.LPWStr)] string domainName,
        [MarshalAs(UnmanagedType.LPWStr)] string displayName,
        uint flags);

 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
    uint OpenDSGPO(
        [MarshalAs(UnmanagedType.LPWStr)] string path,
        uint flags);

    uint OpenLocalMachineGPO(
        uint flags);

    uint OpenRemoteMachineGPO(
        [MarshalAs(UnmanagedType.LPWStr)] string computerName,
        uint flags);

    uint Save(
        [MarshalAs(UnmanagedType.Bool)] bool machine,
        [MarshalAs(UnmanagedType.Bool)] bool add,
        [MarshalAs(UnmanagedType.LPStruct)] Guid extension,
        [MarshalAs(UnmanagedType.LPStruct)] Guid app);

    uint Delete();

    uint GetName(
        [MarshalAs(UnmanagedType.LPWStr)] StringBuilder name,
        int maxLength);

    uint GetDisplayName(
        [MarshalAs(UnmanagedType.LPWStr)] StringBuilder name,
        int maxLength);

    uint SetDisplayName(
        [MarshalAs(UnmanagedType.LPWStr)] string name);

    uint GetPath(
        [MarshalAs(UnmanagedType.LPWStr)] StringBuilder path,
        int maxPath);

    uint GetDSPath(
        uint section,
        [MarshalAs(UnmanagedType.LPWStr)] StringBuilder path,
        int maxPath);

    uint GetFileSysPath(
        uint section,
        [MarshalAs(UnmanagedType.LPWStr)] StringBuilder path,
        int maxPath);

    uint GetRegistryKey(
        uint section,
        out IntPtr key);

    uint GetOptions();

    uint SetOptions(
        uint options,
        uint mask);

    uint GetType(
        out IntPtr gpoType
    );

    uint GetMachineName(
        [MarshalAs(UnmanagedType.LPWStr)] StringBuilder name,
        int maxLength);

    uint GetPropertySheetPages(
        out IntPtr pages);
}