您的安装程序不会在登录的用户会话下运行,而是在本地系统会话下运行。这就解释了为什么HKCU
指向另一个注册表配置单元。
为了打开登录用户的注册表项,您需要打开此注册表项HKU/<LOGGED_ON_USER_SID>
。您可以通过 Windows 会话 API 获取此 SID(安全标识符)。
您可以使用Microsoft.Win32.Registry.Users
代替Microsoft.Win32.Registry.CurrentUser
并根据用户 SID 打开正确的用户密钥。
例如,您可以在 stackoverflow 上找到有关如何获取当前登录的 SID 的多个主题如何在 Windows 中获取当前用户登录会话的唯一 ID - c#
更新:能够获取登录用户 SID 字符串的示例代码,它只能在系统会话中工作,因为它需要特殊权限SE_TCB_NAME
。为了简单起见,没有错误处理
static void Main(string[] args)
{
Microsoft.Win32.RegistryKey mykey;
mykey = Microsoft.Win32.Registry.Users.CreateSubKey(GetLoggedOnUserSID() + "\\Software\\Microsoft\\Windows\\Muhil Software");
mykey.SetValue("Muhil", "TEST");
mykey.Close();
}
enum TokenInformationClass
{
TokenOwner = 4,
}
struct TokenOwner
{
public IntPtr Owner;
}
[DllImport("advapi32.dll", EntryPoint = "GetTokenInformation", SetLastError = true)]
static extern bool GetTokenInformation(
IntPtr tokenHandle,
TokenInformationClass tokenInformationClass,
IntPtr tokenInformation,
int tokenInformationLength,
out int ReturnLength);
[DllImport("kernel32.dll")]
private static extern UInt32 WTSGetActiveConsoleSessionId();
[DllImport("wtsapi32.dll", SetLastError = true)]
static extern bool WTSQueryUserToken(UInt32 sessionId, out IntPtr Token);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool ConvertSidToStringSid(IntPtr sid, [In, Out, MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid);
static string GetLoggedOnUserSID()
{
IntPtr tokenOwnerPtr;
int tokenSize;
IntPtr hToken;
// Get a token from the logged on session
// !!! this line will only work within the SYSTEM session !!!
WTSQueryUserToken(WTSGetActiveConsoleSessionId(), out hToken);
// Get the size required to host a SID
GetTokenInformation(hToken, TokenInformationClass.TokenOwner, IntPtr.Zero, 0, out tokenSize);
tokenOwnerPtr = Marshal.AllocHGlobal(tokenSize);
// Get the SID structure within the TokenOwner class
GetTokenInformation(hToken, TokenInformationClass.TokenOwner, tokenOwnerPtr, tokenSize, out tokenSize);
TokenOwner tokenOwner = (TokenOwner)Marshal.PtrToStructure(tokenOwnerPtr, typeof(TokenOwner));
// Convert the SID into a string
string strSID = "";
ConvertSidToStringSid(tokenOwner.Owner, ref strSID);
Marshal.FreeHGlobal(tokenOwnerPtr);
return strSID;
}