服务中访问当前用户注册表信息
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 }
代码里只实现了读取注册表的信息,改写和写入类似。