簡體   English   中英

將注冊表寫入hkey_current_user而不是hkey_users

[英]write registry to hkey_current_user instead of hkey_users

我嘗試將注冊表子項及其對應的值寫入注冊表,如下所示:

Microsoft.Win32.RegistryKey mykey;
mykey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Windows\\Muhil Software");
mykey.SetValue("Muhil", "TEST");
mykey.close();

正如你所看到的,我用CurrentUser寫值HKEY_CURRENT_USER ,沒有什么HKEY_CURRENT_USER 然后我檢查了HKEY_USERS的子項,發現密鑰寫在那里。

您的安裝程序不會在登錄的用戶會話下運行,而是在本地系統會話下運行。 這就解釋了為什么HKCU指向另一個注冊表配置單元。

要打開登錄用戶的注冊表項,您需要打開此注冊表項HKU/<LOGGED_ON_USER_SID> 借助Windows Session 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;        
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM