2013-12-23 78 views

回答

2

我發現的工作解決方案是使用組策略對象COM + API接口。

備註:

  • 線程標記爲STA必須使用。它可以應用於整個應用程序或只是一個線程;

  • COM + IGroupPolicyObject必須通過ComInterop使用;

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