2

我有一个 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: Access Denied ?


这可能是原因吗?

关于 CreateProcessWithLogonW 的 MSDN 文章说:

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

我正在使用 Windows 7 PRO x64

4

2 回答 2

3

您正在LocalSystem帐户下运行该服务,并且正如文档中明确指出的那样:

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

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

于 2012-11-30T22:38:40.813 回答
0

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

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

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

于 2012-11-29T14:24:34.067 回答