2015-11-18 2 views
1

У меня проблема с сервисом Windows, над которым я работаю в настоящее время. В основном я сохраняю некоторые значения в реестре HKCU (из инструмента GUI запускается как администратор), и из этого графического интерфейса я запускаю службу. Служба использует учетную запись SYSTEM для запуска, и я считаю, что это моя проблема. Я не могу получить доступ к ключам реестра, хранящимся в моем GUI-инструменте внутри службы, поскольку это указывает на другой HKCU!C# Реестр доступа другого пользователя

Как я могу «перенаправить» службу на использование HKCU пользователя, с которым он был сохранен? (На самом деле я могу передать имя пользователя службе или SID, если кто-то укажет мне, как получить ее в моем графическом интерфейсе, но я не знаю, что я должен использовать, чтобы «изменить» пользователя, чтобы указать на правильный)

@EDIT

Я использую статический класс для доступа к реестру, он используется как графический интерфейс и службы и функции, чтобы получить базовый ключ (это строка корневого раздела переменную, содержащую имя подраздела):

private static RegistryKey GetBaseKey(bool writable = false) 
     { 
      try 
      { 
       RegistryKey reg = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64); 
       RegistryKey rk = reg?.OpenSubKey("SOFTWARE", writable)?.OpenSubKey(rootKey, writable); 

       return rk; 
      } 
      catch (Exception ex) 
      { 
       // handle exceptions later 
      } 

      return null; 
     } 

Я нашел класс WindowsIdentity, который может предоставить дескриптор (AccessToken) для текущего пользователя, должен ли я передать его в качестве аргумента моей службе и использовать этот дескриптор для олицетворять внутри службы?

@ EDIT2

Я сделал некоторые вещи, но он не работает. То, что я пробовал:

CurrentUserToken = WindowsIdentity.GetCurrent().Token; // to get current identity token 

затем ServiceController.Start я добавил CurrentUserToken.ToString() в качестве аргумента. В моей службы я инициализируется RegistryUserToken (IntPtr) с переданным значением, и я застрял на:

WindowsIdentity RegUser = new WindowsIdentity(RegistryUserToken) 

бросали за исключением

недопустимый маркер для перевоплощения - это не может быть повторен

Я попытался то же самое с AccessToken текущего экземпляра WindowsIdentity - то же самое исключение, вызванное

Могу ли я вообще пойти так? Или я должен попробовать что-то другое?

+0

Показать Ваш код. Как вы работаете с реестром? –

+0

Добавлен «главный» метод реестра, все остальные методы используют его для получения подраздела для работы. – user1970395

+0

Вы можете просто запустить службу Windows под учетной записью пользователя. –

ответ

1

Хорошо, мне удалось решить проблему несколько иначе. Я добавил переменную SID в свой класс реестра, и если она не равна нулю, я открываю «Узел реестра пользователей» вместо HKCU.Сначала я получить пользователь текущего в SID (в пределах моего GUI приложения) с помощью:

WindowsIdentity.GetCurrent().User.ToString(); 

, который я прохожу в качестве аргумента в мою службу и установить его для класса реестра.

5

Я могу дать вам два варианта: олицетворять этого пользователя, если у вас есть свои учетные данные, или использовать идею о том, что HKCU является символической ссылкой для одного из ключей под HKEY_USERS. Для выдачи заимствования вы можете увидеть this link. Если вы знаете SID этого пользователя, вы можете найти его там. Вы можете получить SID так:

var account = new NTAccount("usernameThatYouNeed"); 
var identifier = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier)); 
var sid = identifier.Value; 

Я предпочитаю олицетворять. Второй вариант - для случая, если вы не знаете его учетные данные. Мне не нравится второй вариант, потому что он требует административных прав на запись в чужую учетную запись.

+0

На самом деле я считаю, что могу использовать олицетворение с момента запуска GUI сначала (как администратора), с помощью инструмента GUI я сохраняю эти значения (в реестре HKCU), и из этого графического интерфейса я запускаю службу, поэтому я может (может я?) восстановить текущий идентификатор пользователя в коде GUI и передать его службе, не так ли? – user1970395

+0

обновил мой вопрос тем, что я сделал, и где я застрял, надеюсь, вы поможете мне в этом. – user1970395

1

Мне нужно было прочитать реестр другого пользователя из службы. Вот как я работал, но в этом случае я знаю точное имя пользователя. Другие ответы здесь помогли. Имя пользователя и путь - все, что вам нужно.

 NTAccount f = new NTAccount("yourUserName"); 
     SecurityIdentifier s = (SecurityIdentifier)f.Translate(typeof(SecurityIdentifier)); 
     String sidString = s.ToString(); 

     Microsoft.Win32.RegistryKey OurKey = Microsoft.Win32.Registry.Users; 
     OurKey = OurKey.OpenSubKey(sidString + "\\SOFTWARE\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\AppContainer\\Mappings", true); 

     if (OurKey != null) { 
      foreach (string Keyname in OurKey.GetSubKeyNames()) 
      { 
Смежные вопросы