C#访问另一个用户

时间:2015-11-18 10:31:13

标签: c# windows-services registry uac

我目前正在使用的Windows服务出现问题。基本上我在HKCU注册表中存储了一些值(来自以管理员身份运行的GUI工具),并且在该GUI中我正在启动服务。该服务使用SYSTEM帐户运行,我相信这是我的问题 - 我无法访问存储在我的GUI工具中的注册表项,因为它指向不同的HKCU!

我如何"重定向"使用它的用户HKCU的服务? (实际上我可以将用户名传递给服务或SID,如果有人会指出我如何在我的GUI中检索它,但我不知道我应该使用什么来改变"用户改为指向正确的一个)

@EDIT

我使用静态类来访问注册表,它由GUI和Service使用,并且检索基本密钥的函数是(rootKey是保存子项名称的字符串变量):

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;
        }

我找到了可以为当前用户提供句柄(AccessToken)的WindowsIdentity类,我应该将其作为参数传递给我的服务并使用此句柄来模拟服务内部吗?

@ EDIT2

我做过一些事情,但它没有用。我尝试了什么:

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

然后使用ServiceController.Start我添加了CurrentUserToken.ToString() 作为一个论点。在我的服务中,我使用传递的值初始化RegistryUserToken (IntPtr)并且我坚持:

WindowsIdentity RegUser = new WindowsIdentity(RegistryUserToken)

抛出异常

  

用于模拟的令牌无效 - 无法复制

我对WindowsIdentity的当前实例的AccessToken尝试了相同的操作 - 抛出相同的异常

我可以这样走吗?或者我应该尝试不同的东西?

3 个答案:

答案 0 :(得分:5)

我可以给你两个选择:如果你有他们的凭据冒充那个用户,或者使用HKCU是HKEY_USERS下其中一个键的符号链接。 冒充你可以看到this link。 如果您知道该用户的SID,那么您可以在那里找到它。你可以这样得到SID:

byte[] buffer = new byte[65536];
var bytesNeeded = buffer.Length;

var fileStream = new FileStream("filename.ext", FileMode.Open, FileAccess.Read);

if (bytesNeeded > fileStream.Length)
    bytesNeeded = (int)fileStream.Length;

FileReader.ReadBytes(fileStream, buffer, 0, bytesNeeded, () =>
{
    Trace.WriteLine("done");
});

我更喜欢冒充。如果您不知道用户的凭据,则第二种选择是针对具体情况的。 我不喜欢第二种选择,因为它需要管理权限才能写入其他人的帐户。

答案 1 :(得分:1)

好吧,我已经设法以一种不同的方式解决它。我已经将SID变量添加到我的Registry类中,如果它不为null,那么我打开Users Registry Hive而不是HKCU。首先,我使用:

检索当前用户的SID(在我的GUI应用程序中)
WindowsIdentity.GetCurrent().User.ToString();

我将其作为参数传递给我的服务并将其设置为Registry类。

答案 2 :(得分:1)

我需要从服务中读取另一个用户的注册表。这就是我如何工作,但在这种情况下,我知道确切的用户名。这里的其他答案帮了很多忙。用户名和路径是您需要的任何内容。

<span> <img src="https://cdn4.iconfinder.com/data/icons/imoticons/105/imoticon_15-128.png" /> 
   
Active<img id="edit" title="click to edit" src="https://cdn4.iconfinder.com/data/icons/imoticons/105/imoticon_12-128.png" /></span>