服务返回代码 5 中的 CreateProcessWithLogonw:访问被拒绝

Posted

技术标签:

【中文标题】服务返回代码 5 中的 CreateProcessWithLogonw:访问被拒绝【英文标题】:CreateProcessWithLogon in service returning code 5: access denied 【发布时间】:2012-11-29 13:09:32 【问题描述】:

我有一个 StartType = stSystem 的 Windows 服务。

它使用 CreateProcessWithLogonW 执行应用程序。

 usr := 'myuser';
 dmn := 'mydomain';
 pwd := 'thepassword';
 cmd := 'c:\myapp.exe -calculate';
 wdir := 'c:\';

 fillchar(si, sizeof(si), 0);
 si.cb := sizeof(si);

 if not CreateProcessWithLogon(
           PWideChar(usr),
           PWideCharOf(dmn),
           PWideChar(pwd),
           LOGON_WITH_PROFILE,
           nil,
           PWideChar(cmd),
           NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP,
           nil,
           PWideChar(wdir),
           si,
           pi
         )
        then
          RaiseLastOSError; // raises Code 5: Access Denied

在服务之外运行这段代码,一切正常!

为什么 CreateProcessWithLogon 会引发系统错误代码 5:访问被拒绝?


可能是这个原因吗?

MSDN article on CreateProcessWithLogonW 说:

带有 SP2 和 Windows Server 2003 的 Windows XP:您不能从在 LocalSystem 帐户下运行的进程调用 CreateProcessWithLogonW,因为该函数使用调用者令牌中的登录 SID,而 LocalSystem 帐户的令牌不包含此西德。或者,使用 CreateProcessAsUser 和 LogonUser 函数。

我使用的是 Windows 7 PRO x64

【问题讨论】:

您能指定服务运行的用户帐户吗?它可以是 LocalSystem、NetworkService、命名用户等。 服务作为 LocalSystem 运行 如果不使用 LOGON_WITH_PROFILE 会怎样? 我在下面添加了有关检查 Windows 事件日志的注释,因此您可以尝试下一个。 您在 LocalSystem 帐户下运行该服务,并且正如文档所述:“您不能从在 LocalSystem 帐户下运行的进程调用 CreateProcessWithLogonW”。因此,要么更改运行服务的用户帐户,要么切换到CreateProcessAsUser(),如文档所述。 【参考方案1】:

您在 LocalSystem 帐户下运行服务,正如the documentation 明确表示:

您不能从在 LocalSystem 帐户下运行的进程调用 CreateProcessWithLogonW,因为该函数使用调用者令牌中的登录 SID,而 LocalSystem 帐户的令牌不包含此 SID。

因此,要么更改运行服务的用户帐户,要么切换到CreateProcessAsUser(),如文档所述。

【讨论】:

【参考方案2】:

LocalSystem 帐户应该有足够的权限来读取和执行本地系统上的任何程序(除非您遇到了特定的麻烦来拒绝它访问某些东西)。鉴于此,我猜测您正在执行的程序可能驻留在其他计算机上。这将导致失败的原因是因为 LocalSystem 没有网络身份并且通常无法访问远程共享。您能否检查该程序是否确实驻留在本地驱动器上,而不是网络共享(可能被映射驱动器屏蔽)?

如果这不是问题,我会尝试使用ProcMon 来调试问题。这将显示系统上的所有文件和注册表活动,包括成功访问和失败。如果你运行它然后重现问题,我希望你会看到一个结果为 ACCESS DENIED 的条目,这应该指向你的原因。您可以使用过滤功能将输出限制为您的服务进程和您正在生成的进程。如果您在 Vista/2008 或更高版本上运行,则需要以提升的权限运行 ProcMon。

您还可以检查 Windows 事件日志,尤其是安全日志。如果尚未启用,您可能需要enable audit logging;我将启用“审计对象访问”、“审计登录事件”、“审计帐户登录事件”和“审计权限使用”,包括成功和失败。根据我的经验,这些更改可能需要一段时间才能生效,因此如果您没有开始看到日志,您可能会重新启动测试系统。一旦日志记录工作,重试 CreateProcessWithLogon 并查看出现了哪些事件。您还可以将事情正常时产生的一系列事件与事情不工作时产生的一系列事件进行比较,这可能有助于找出问题所在。

【讨论】:

该文件可在本地系统访问。我已经尝试过 ProcMon,但在调用 CreateProcessWithLogon 期间没有报告任何问题... 也尝试过审计,但没有成功。 CreateProcessWithLogon 的文档清楚地说明了失败的原因。

以上是关于服务返回代码 5 中的 CreateProcessWithLogonw:访问被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

我可以访问从 Delphi CreateProcess 命令返回的字符串吗?

CreateProcess 杀死 PC

CreateProcess 返回非 0 但 GetExitCodeProcess() 返回 128

在金蝶K3建立帐套时报错 无法创建数据库!错误描述:错误5来自CreateProcess(第737行)

金蝶K3在建立帐套时出现无法创建数据库,错误xpsql.cpp,错误5来自createprocess

CreateProcess 和命令行参数