gpt4 book ai didi

c# - 访问模拟用户的 CurrentUser 注册表项 - 与 .NET 3.5 的兼容性

转载 作者:行者123 更新时间:2023-12-02 05:04:36 25 4
gpt4 key购买 nike

我最近编写了一个模拟用户帐户的应用程序,获取 CURRENT_USER 注册表项的句柄(使用 PInvoke“LoadUserProfile”检索 ProfileInfo.hProfile 对象)并使用 RegistryKey.FromHandle 创建注册表项。

引用代码:

using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(hToken))
{
using (SafeRegistryHandle safeHandle = new SafeRegistryHandle(hProfile, true))
{
using (RegistryKey impersonatedUserHkcu = RegistryKey.FromHandle(safeHandle, RegistryView.Default))
{
// Do something with registry
}
}
}

这段代码运行良好(在 Windows 7 中运行),但使用了仅受 .NET 4.0 及更高版本支持的对象/方法(SafeRegistryHandle、RegistryKey.FromHandle()、RegistryView 枚举)。

现在,我需要使这个应用程序与 .NET 3.5 兼容,以便在装有 Windows XP 的机器上使用它,并且不可能安装 .NET Framework 4.0。

是否有任何等效对象可以与 .NET 3.5 一起使用来实现相同的结果? (即,为模拟用户修改注册表项)。还是仅存在 .NET 4 对象的某种源代码?

最佳答案

经过几天的研究,and help from MSDN community to the same question ,我找到了满足我的需求的方法。

最初的建议是使用 Win Api 函数 RegOpenKeyEx(有关信息和示例,请参阅 P/Invoke website);但根据this MSDN article , 我发现了

If your service or application impersonates different users, do not use this function with HKEY_CURRENT_USER. Instead, call the RegOpenCurrentUser function.

最后,要走的路是 RegOpenCurrentUser 函数。 (不幸的是,在 P/Invoke 网站上仍然没有关于此功能的踪迹,但您可以找到一些信息 on MSDN )

我目前是这样定义它的:

[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 GetImpersonateUserRegistryHandle(RegistrySecurity _access)
{
IntPtr safeHandle = new IntPtr();
int result = RegOpenCurrentUser((int)_access, out safeHandle);

return safeHandle;
}

/// <summary>
/// Get a registry key from a pointer.
/// </summary>
/// <param name="hKey">Pointer to the registry key</param>
/// <param name="writable">Whether or not the key is writable.</param>
/// <param name="ownsHandle">Whether or not we own the handle.</param>
/// <returns>Registry key pointed to by the given pointer.</returns>
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;
}

这就是我使用它获取注册表的方式:

IntPtr localRegistryHandle = GetImpersonateUserRegistryHandle(TestRegistryAccess.RegistrySecurity.KEY_ALL_ACCESS);

using(RegistryKey localRegistry = _pointerToRegistryKey(localRegistryHandle, true, true))
{
// do something with local registry
}

关于c# - 访问模拟用户的 CurrentUser 注册表项 - 与 .NET 3.5 的兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16477370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com