注册表项对于从服务运行的应用程序不可用

注册表项对于从服务运行的应用程序不可用

我们正在编写一个自定义 Windows 服务应用程序。该服务设置为允许与桌面交互,并且该服务应用程序将需要执行另一个“正常”应用程序。该服务设置为使用正常 Windows 用户帐户(而不是系统帐户)启动和运行。

我们遇到的问题是,当服务调用其他正常应用程序时,似乎注册表未加载,而当服务以用户帐户身份登录 Windows 时则不会加载。具体来说,应用程序抛出错误,指出某些注册表项不可用。

为什么运行服务的帐户没有收到相同用户帐户登录同一 Windows 系统时收到的完整注册表?有什么办法可以改变这种情况吗?

答案1

服务帐户不会加载用户配置文件,因此无法访问 HKCU 注册表配置单元。此类服务的设置应保存在 HKLM 中,并根据需要在键上放置适当的安全设置。但是,如果配置文件已加载到系统中,如果您深入挖掘它,它应该存在于 HKU 下的某个地方。

答案2

我认为这里还发生了其他事情。

用户是否与服务同时登录?如果是,注册表配置单元可能被锁定。Windows 事件日志中是否有任何消息?

我认为该应用程序应该能够访问 HKEY_CURRENT_USER 注册表的原因是我对此进行了测试并创建了一个示例 C# Windows 服务(如果感兴趣的话,请参阅下面的代码)。

但是,设计为作为服务运行的应用程序不应将其信息存储在 HKCU 寄存器配置单元中。HKLM 是系统范围应用程序设置的正确位置。

测试执行

我在 Windows 7 下创建了一个具有管理权限的新用户帐户。然后我授予它以服务身份登录权限,安装并启动了该服务。

我的发现是:* 当我运行服务时,HKCU 已加载并可写入。* 当配置单元已加载时,我在事件日志中收到此消息,并且实际配置单元未更新。而是创建了一个临时配置单元。

Windows 无法加载注册表。此问题通常是由于内存不足或安全权限不足造成的。

详细信息 - 该进程无法访问该文件,因为该文件正在被另一个进程使用。对于 C:\Users\OtherService\ntuser.dat

http://msdn.microsoft.com/en-us/library/ms684190(v=VS.85).aspx和这里http://msdn.microsoft.com/en-us/library/ms684188(v=VS.85).aspx表明即使默认系统帐户也有一个加载到 HKCU 的注册表配置单元,尽管它可能是共享的。

测试服务代码

public partial class ExecuterSvc : ServiceBase
{
    public ExecuterSvc()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        TagRegistryHive("Tag", "Written");
    }

    protected override void OnStop()
    {

    }

    public void TagRegistryHive(string KeyName, object Value)
    {
        try
        {
            // Load the hive.
            var rk = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default);

            rk.SetValue(KeyName.ToUpper(), Value);
        }
        catch (Exception e)
        {

        }
    }
}

相关内容