2013-01-08 48 views
6

我们正在开发一个C#.NET窗口服务。模拟用户

我们的服务正在系统帐户下运行,我们正试图模拟登录的用户USER。 模拟工作正常,即在模拟后调用System.Security.Principal.WindowsIdentity.GetCurrent()时,我们得到正确的用户'USER'。

问题是,当我们尝试访问用户配置文件时,我们没有得到预期的结果。 一个例子是访问注册表CURRENT_USER。我们得到一个访问被拒绝的错误。 使用我们假设部分使用注册表的第三方功能时,我们会获取“真实”(模拟前)用户的详细信息。 此外,在拨打Environment.ExpandEnvironmentVariables("%TEMP%")时,我们将获取系统配置文件,而不是登录的用户配置文件。

有没有办法完全模仿不同的用户? 我知道我们可以使用LoadUserProfile来获取特定的用户配置文件,但这对我们并不好,因为我们正在运行使用当前用户配置文件的第三方dll。

我们的模拟代码在this

+1

首先,你应该使用System.IO.Path.GetTempPath();如果仍然不起作用,这可能是你的问题:http://stackoverflow.com/questions/944483/how-to-get-temporary-folder-for-current-user看到接受的答案,以及它是如何工作的。 – lahsrah

+0

让我更具体。我们正在使用对我们无法更改的第三方dll的调用。所以如果他们预计特定的用户配置文件,我们必须使该进程与该用户配置文件一起运行。 – user844541

+0

@ user844541请再次阅读我的链接。 – lahsrah

回答

2

我注意到代码不调用LoadUserProfile基地,使用户配置文件没有加载。

注意在该函数的注释中,HKEY_CURRENT_USER仍然没有被替换。

认为您可以通过调用RegOverridePredefKey来解决此问题(在调用第三方DLL之前)。

请注意,很多伏都教可能涉及到这一切的工作权利 - 我会尽力确保覆盖发生在第三方呼叫之前尽可能晚,并尽快恢复后(希望这是对图书馆的一次调用)。

作为一种替代方案,我会认真尝试寻找不同的第三方产品,不需要所有这些都会跳出来。

+0

在这种情况下调用'RegOverridePredefKey'将无济于事,因为每个进程都是进程模拟,而每个线程都是模拟。 – Ben

2

正如您发现的那样,模拟不会设置HKEY_CURRENT_USER或环境。

这是因为模拟令牌是每个线程,并且HKCU和环境是每个进程。

如果您需要访问用户的常用环境,则需要使用HKEY_USERS\SID和模拟用户的SID,例如例如HKEY_USERS\S-1-5-21-12345678-12345678-12345678-1234。致电LoadUserProfile确保密钥已加载。 (如果它应该是当前登录的用户,它应该已经加载,所以你可能不应该那样做,但检查它是否存在并且如果不存在则返回一个错误)。

你也可以计算出他们平常的环境,因为这是在HKCU内的关键“环境”之下。你只需要将它与系统环境结合起来。

如果第三方DLL实际需要HKCU并且环境设置正确,则需要在用户的登录会话中创建一个进程来承载DLL,并以某种方式发送任何操作的结果。如果只需要环境,则可以创建子进程并手动设置环境。

但是你还没有说过你为什么要这样做。这听起来像你已经解决了这个问题,作为解决更大问题的一部分。如果可能的话,我建议你看看是否有办法做到你所需要的,而不需要获取用户的环境或HKCU。

为什么不能直接在用户自己的会话中运行该DLL?为什么需要一项服务?您是否可以重新构建解决方案,以便在登录会话中运行用户模式部分并承载第三方DLL,并与服务进行通信,以便该服务仅执行绝对必需的部分?

+0

+1有关在用户会话中运行某些内容的建议。几乎每次我遇到类似的服务和用户帐户问题时,都是这样。 – Basic