C# 为模拟用户访问HKCU:P/Invoke";RegOpenCurrentUser";在Windows XP中返回空句柄

C# 为模拟用户访问HKCU:P/Invoke";RegOpenCurrentUser";在Windows XP中返回空句柄,c#,registry,pinvoke,impersonation,C#,Registry,Pinvoke,Impersonation,我无法访问模拟用户的HKEY_CURRENT_用户注册表项 经过一些研究,我目前正在使用Win32 ApiRegOpenCurrentUser。 由于P/Invoke网站中没有文档,我从以下网站上找到了此签名: 我是这样用的: public class LocalRegistryAccess { [DllImport("advapi32.dll", CharSet = CharSet.Auto)] public static extern int RegOpenCurrentUs

我无法访问模拟用户的HKEY_CURRENT_用户注册表项

经过一些研究,我目前正在使用Win32 Api
RegOpenCurrentUser
。 由于P/Invoke网站中没有文档,我从以下网站上找到了此签名:

我是这样用的:

public class LocalRegistryAccess
{
    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    public static extern int RegOpenCurrentUser(int samDesired, out IntPtr phkResult);

    public enum RegistrySecurity
    {
        KEY_ALL_ACCESS = 0xF003F,
        KEY_CREATE_LINK = 0x0020,
        KEY_CREATE_SUB_KEY = 0x0004,
        KEY_ENUMERATE_SUB_KEYS = 0x0008,
        KEY_EXECUTE = 0x20019,
        KEY_NOTIFY = 0x0010,
        KEY_QUERY_VALUE = 0x0001,
        KEY_READ = 0x20019,
        KEY_SET_VALUE = 0x0002,
        KEY_WOW64_32KEY = 0x0200,
        KEY_WOW64_64KEY = 0x0100,
        KEY_WRITE = 0x20006,
    }

    public IntPtr GetImpersonatedUserRegistryHandle(RegistrySecurity _access)
    {
        IntPtr safeHandle = new IntPtr();
        int result = RegOpenCurrentUser((int)_access, out safeHandle);

        return safeHandle;
    }

    public RegistryKey _pointerToRegistryKey(IntPtr hKey, bool writable, bool ownsHandle)
    {
        //Get the BindingFlags for private contructors
        System.Reflection.BindingFlags privateConstructors = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic;

        //Get the Type for the SafeRegistryHandle
        Type safeRegistryHandleType = typeof(Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType("Microsoft.Win32.SafeHandles.SafeRegistryHandle");

        //Get the array of types matching the args of the ctor we want
        Type[] safeRegistryHandleCtorTypes = new Type[] { typeof(IntPtr), typeof(bool) };

        //Get the constructorinfo for our object
        System.Reflection.ConstructorInfo safeRegistryHandleCtorInfo = safeRegistryHandleType.GetConstructor(privateConstructors, null, safeRegistryHandleCtorTypes, null);

        //Invoke the constructor, getting us a SafeRegistryHandle
        Object safeHandle = safeRegistryHandleCtorInfo.Invoke(new Object[] { hKey, ownsHandle });

        //Get the type of a RegistryKey
        Type registryKeyType = typeof(RegistryKey);

        //Get the array of types matching the args of the ctor we want
        Type[] registryKeyConstructorTypes = new Type[] { safeRegistryHandleType, typeof(bool) };

        //Get the constructorinfo for our object
        System.Reflection.ConstructorInfo registryKeyCtorInfo = registryKeyType.GetConstructor(privateConstructors, null, registryKeyConstructorTypes, null);

        //Invoke the constructor, getting us a RegistryKey
        RegistryKey resultKey = (RegistryKey)registryKeyCtorInfo.Invoke(new Object[] { safeHandle, writable });

        //return the resulting key
        return resultKey;
    }
}

public class UserManagement
{
    LocalRegistryAccess regAccess = new LocalRegistryAccess();

    using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(token))
    {
        IntPtr localRegistryHandle = regAccess.GetImpersonatedUserRegistryHandle(LocalRegistryAccess.RegistrySecurity.KEY_ALL_ACCESS);
        using(RegistryKey localRegistry = regAccess._pointerToRegistryKey(localRegistryHandle, true, true))
        {
            // Manage HKCU for impersonated user
        }
    }
}
此代码似乎在Windows 7上正常工作,但在Windows XP Embedded中不起作用:my method
GetImpersonatedUserRegistryHandle
始终返回空句柄


有什么想法吗?为了使此代码与Windows XP Embedded兼容,我是否缺少一些说明?

int result=RegOpenCurrentUser(…)的值是多少?@SimonMourier:这很奇怪。。。我刚才重复了这个测试,
int result=RegOpenCurrentUser(…)
返回
result=0
,带有有效句柄,没有任何错误。今天早上我做测试时,它返回了一个
handle=0
,但我不记得
result
.P.S.:我从昨天起就没有对代码做过任何更改。千万不要用try/catch括住你的pinvoke,这样仍然会隐藏错误。包括那些你不想隐藏的非常讨厌的东西,比如访问冲突。即使是你,在C++中编写代码也会更容易。这是相同的代码,但没有所有可怕的p/invoke。关于错误处理,Hans建议您开始检查代码中的错误,而不是忽略它们。Win32 api调用不会抛出,因此您必须检查每个函数的文档中所述的错误。你需要开始这样做。
public class LocalRegistryAccess
{
    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    public static extern int RegOpenCurrentUser(int samDesired, out IntPtr phkResult);

    public enum RegistrySecurity
    {
        KEY_ALL_ACCESS = 0xF003F,
        KEY_CREATE_LINK = 0x0020,
        KEY_CREATE_SUB_KEY = 0x0004,
        KEY_ENUMERATE_SUB_KEYS = 0x0008,
        KEY_EXECUTE = 0x20019,
        KEY_NOTIFY = 0x0010,
        KEY_QUERY_VALUE = 0x0001,
        KEY_READ = 0x20019,
        KEY_SET_VALUE = 0x0002,
        KEY_WOW64_32KEY = 0x0200,
        KEY_WOW64_64KEY = 0x0100,
        KEY_WRITE = 0x20006,
    }

    public IntPtr GetImpersonatedUserRegistryHandle(RegistrySecurity _access)
    {
        IntPtr safeHandle = new IntPtr();
        int result = RegOpenCurrentUser((int)_access, out safeHandle);

        return safeHandle;
    }

    public RegistryKey _pointerToRegistryKey(IntPtr hKey, bool writable, bool ownsHandle)
    {
        //Get the BindingFlags for private contructors
        System.Reflection.BindingFlags privateConstructors = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic;

        //Get the Type for the SafeRegistryHandle
        Type safeRegistryHandleType = typeof(Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType("Microsoft.Win32.SafeHandles.SafeRegistryHandle");

        //Get the array of types matching the args of the ctor we want
        Type[] safeRegistryHandleCtorTypes = new Type[] { typeof(IntPtr), typeof(bool) };

        //Get the constructorinfo for our object
        System.Reflection.ConstructorInfo safeRegistryHandleCtorInfo = safeRegistryHandleType.GetConstructor(privateConstructors, null, safeRegistryHandleCtorTypes, null);

        //Invoke the constructor, getting us a SafeRegistryHandle
        Object safeHandle = safeRegistryHandleCtorInfo.Invoke(new Object[] { hKey, ownsHandle });

        //Get the type of a RegistryKey
        Type registryKeyType = typeof(RegistryKey);

        //Get the array of types matching the args of the ctor we want
        Type[] registryKeyConstructorTypes = new Type[] { safeRegistryHandleType, typeof(bool) };

        //Get the constructorinfo for our object
        System.Reflection.ConstructorInfo registryKeyCtorInfo = registryKeyType.GetConstructor(privateConstructors, null, registryKeyConstructorTypes, null);

        //Invoke the constructor, getting us a RegistryKey
        RegistryKey resultKey = (RegistryKey)registryKeyCtorInfo.Invoke(new Object[] { safeHandle, writable });

        //return the resulting key
        return resultKey;
    }
}

public class UserManagement
{
    LocalRegistryAccess regAccess = new LocalRegistryAccess();

    using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(token))
    {
        IntPtr localRegistryHandle = regAccess.GetImpersonatedUserRegistryHandle(LocalRegistryAccess.RegistrySecurity.KEY_ALL_ACCESS);
        using(RegistryKey localRegistry = regAccess._pointerToRegistryKey(localRegistryHandle, true, true))
        {
            // Manage HKCU for impersonated user
        }
    }
}