服务中访问当前用户注册表信息

  Windows Vista后有session 0隔离机制,那么在服务中是不能直接访问当前登录用户的注册表信息的,因为此时的HKEY_CURRENT_USER是里面是system的。那么实在需要,该怎么做呢?方法还是有的,在网上搜了一下,如下两个链接提供了一些方法:

  http://blog.csdn.net/zwh37333/article/details/6358725

  http://blog.csdn.net/ly402609921/article/details/9127959

但是很不幸,我要用C#来实现这个过程,我不知道怎么去定义包含SID信息的结构体,但这里的关键就是获取SID,有了它就可以找到要访问的注册表了。所以最后不得不另想他法。不过还真想到了,也借鉴了以上两个帖子中的东西。

我的方法:

  1.C#中有API可以在当前用户的上下文获取当前用户的SID;

  2.在服务中模拟当前用户的上下文,获取SID,注意获取完切回来哦;

  3.去HKEY_USERS下SID[SubKeyPath]下访问所需的注册表信息。

C#代码:

 1 using System;
 2 using System.Security;
 3 using System.Diagnostics;
 4 using System.Runtime.InteropServices;
 5 using System.Security.Principal;
 6 using Microsoft.Win32;
 7 
 8 namespace Toolkit
 9 {
10     public class AccessCurrentUserReg
11     {
12         #region Win32 API Imports
13 
14         [DllImport("Advapi32.dll", EntryPoint = "ImpersonateLoggedOnUser", SetLastError = true)]
15         private static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
16 
17         [DllImport("Advapi32.dll", EntryPoint = "RevertToSelf", SetLastError = true)]
18         private static extern bool RevertToSelf();
19         
20         [DllImport("kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true)]
21         public static extern bool CloseHandle(IntPtr hSnapshot);
22 
23         [DllImport("kernel32.dll", EntryPoint = "WTSGetActiveConsoleSessionId")]
24         private static extern uint WTSGetActiveConsoleSessionId();
25 
26         [DllImport("Wtsapi32.dll", EntryPoint = "WTSQueryUserToken", SetLastError = true)]
27         private static extern bool WTSQueryUserToken(uint SessionId, ref IntPtr hToken);
28         #endregion
29 
30 
31         public static bool ReadCurrentUserReg(string RegPath, string SubKey, ref string KeyValue)
32         {
33             string CurrentUserSID = string.Empty;
34             if (GetCurrentUserSID(ref CurrentUserSID))
35             {
36                 RegistryKey rsg = Registry.Users.OpenSubKey(CurrentUserSID + "\" + RegPath, false);//false表只读
37                 KeyValue = (string)rsg.GetValue(SubKey);
38                 rsg.Close();
39                 return true;
40             }
41             return false;
42         }
43 
44         public static bool GetCurrentUserSID(ref string CurrentUserSID)
45         {
46             IntPtr hUserToken = IntPtr.Zero;
47             if (ApplicationLoader.GetCurrentUserToken(ref hUserToken))
48             {
49                 if (!ImpersonateLoggedOnUser(hUserToken))//Impersonate Current User logon
50                 {
51                     return false;
52                 }
53                 CloseHandle(hUserToken);
54 
55                 //Obtain Current user SID
56                 WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();
57                 CurrentUserSID = windowsIdentity.User.ToString();
58 
59                 if (!RevertToSelf())//come back
60                 {
61                     LoggerLib.Logger.WriteLog(LoggerLib.Logger.EventSeverity.NOTIFY_SEVERITY_EMERG, string.Format("RevertToSelf()failed!"));
62                 }
63                 return true;
64             }
65             return false;
66         }
67         
68         public static bool GetCurrentUserToken(ref IntPtr hCurrentUserToken)
69         {
70             // obtain the currently active session id; every logged on user in the system has a unique session id
71             uint dwSessionId = WTSGetActiveConsoleSessionId();
72 
73             if (!WTSQueryUserToken(dwSessionId, ref hCurrentUserToken))
74             {                
75                 return false;
76             }
77             return true;
78         }
79     }
80 }
View Code

  代码里只实现了读取注册表的信息,改写和写入类似。

原文地址:https://www.cnblogs.com/darling131499/p/4091108.html