调用枚举作业的访问被拒绝



我正在尝试在Windows Server 2012 R2 Standard上的打印机队列中获取作业的域用户名。 下面的代码片段在德尔福中。OpenPrinter 和 EnumJobs 是 Windows Spooler API 的一部分。

更新!将 maxJobs 设置为更高的 4 倍数允许枚举队列中的更多作业。 例如。 设置 maxJobs=8 允许两个作业,但不允许三个作业。 maxJobs=12 允许三个作业。

解决!看起来我可以忽略 EnumJobs 的返回值,并简单地查看它返回的作业数是否> 0(调用时的最后一个参数)。 这似乎适用于下面列出的所有实例,包括通过共享的打印机。

const
maxJobs = 4;
var
h : THandle;
jia : array [1..maxJobs] of JOB_INFO_1;
jiz, jic : DWord;  // size of jia, count of jia
begin
if OpenPrinter('DocTest', h, nil) then
begin
if EnumJobs(h, 0, maxJobs, 1, @jia, SizeOf(jia), jiz, jic) then  
[...]

枚举作业返回 true 或 false,具体取决于下面列出的不同条件。 如果在以下任何一种情况下返回 false,则我检索的错误消息是"系统错误。 代码:5. 访问被拒绝"。

显然是权限问题。 我已在打印机安全设置中将"打印"、"管理此打印机"和"管理文档"分配给"每个人"。 分配这些设置后,所有作业都已提交。 我的程序正在以域管理员身份登录的会话中运行。

  • 如果我从运行此程序的同一会话打印作业,并且队列中只有一个作业,则 EnumJobs 返回 TRUE。(有关更改,请参阅上面的更新)
  • 如果我以任何用户身份从服务器上的另一个会话(它安装了终端服务)打印,并且队列中只有一个作业,则 EnumJobs 返回 TRUE。 (有关更改,请参阅上面的更新)
  • 如果队列中有多个作业,则枚举作业返回 FALSE。作业是否适用于同一用户并不重要。 (有关更改,请参阅上面的更新)
  • 如果我将作业从另一台服务器打印到打印机共享,则枚举作业返回 FALSE。 两台服务器位于同一域中。 哪个用户打印作业(包括域管理员)无关紧要。

这里发生了什么,特别是在一次枚举超过 (maxJobs/4) 个作业时被拒绝访问?

忽略 EnumJobs 的返回值并检查 out 参数 pcBack 以查看它是否大于 0。 这表示找到的打印作业数。

最新更新