通过 PHP 启动服务器端打印作业
这很可能不是一件容易的事,但情况如下:
我编写了一个 C# 命令行应用程序,该应用程序:
- 使用 ITextSharp 创建 PDF
- 将其写入磁盘
- 使用
Acrord32.exe
(这是 Acrobat Reader)通过 System.Diagnostics.Process 以静默打印生成的 PDF
如果我构建解决方案并双击 pdfGen.exe,它会按预期工作。 PDF 已创建并打印。
现在,我的应用程序必须部署在运行 IIS 7 的 Windows Vista 内部服务器上。该服务器运行一些 PHP Web 应用程序。它将使用 shell_exec()
通过 PHP 调用,以便生成的 PDF 将在连接到服务器的打印机上打印。
所以我的 PHP 页面基本上是这样的:
shell_exec('/path/to/pdfGen.exe');
但这里出了问题。根据任务管理器等发生的情况:
pdfGen.exe
启动- PDF 创建
Acrord32.exe
启动pdfGen.exe
永远挂起(并且PHP 脚本也是如此)并且没有打印任何内容
我很确定这是一些与权限相关的问题。我已经授予 IIS_IUSRS
对默认打印机以及 Acrord32.exe
所在目录的访问权限。但仍然没有打印。但是,如果我手动启动 pdfGen.exe,它就可以工作。
知道我缺少什么吗?
编辑:
我不必使用 Acrobat Reader 来打印 PDF。如果有另一种方法可以静默打印服务器端创建的 PDF,我根本不介意。
This is most likely not an easy one but here is the situation:
I have written a C# command line application which:
- creates a PDF using ITextSharp
- writes it to disk
- uses
Acrord32.exe
(this is Acrobat Reader) viaSystem.Diagnostics.Process
in order to silently print the generated PDF
If I build my solution and double click the pdfGen.exe
, it works as expected. The PDF is created and printed.
Now, my app has to be deployed on a internal server with Windows Vista running IIS 7. This server has some PHP webapp running. And it will be called via PHP using shell_exec()
so that the resulting PDF will be printed on the printer attached to the server.
So my PHP page looks basically like this:
shell_exec('/path/to/pdfGen.exe');
But here things go wrong. What happens is according to task manager etc.:
pdfGen.exe
starts- the PDF is created
Acrord32.exe
startspdfGen.exe
hangs forever (and so does the PHP script) and nothing is printed
I am pretty sure it is some permission related problem. I already gave IIS_IUSRS
access to the default printer, and to the directory where Acrord32.exe
is located. But still, no printing. However, if I start my pdfGen.exe manually it works.
Any idea what I am missing?
EDIT:
I am not bound to use Acrobat Reader in order to print the PDF. If there is another way in order to silently print the created PDF serverside, I would not mind at all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
为了检查发生了什么,请尝试运行
来自 Sysinternals 的进程监视器并筛选到 adobe acrobat 进程的事件。你会看到acrobat的系统调用,它会让你或多或少地知道出了什么问题。
In order to check what is going on, try to run
the process monitor from Sysinternals and filter the events to the adobe acrobat process. You will see the system calls of acrobat and it will allow you to know more or less what is going wrong.
我知道您的解决方案有一个小改进:SumatraPDF 有一个很好的命令行界面,可用于在打印后自动关闭 Sumatra。
我使用PHP“system”或“exec”函数执行批处理文件来打开SumatraPDF:(
您也可以指定要打印的打印机名称)
I know a small improvement to your solution: SumatraPDF has a nice command-line interface that can be used to auto-close Sumatra after printing.
I used PHP "system" or "exec" functions to execute a batch file to open SumatraPDF:
(you can also specify the printer name to print on)
这是一个有趣的计划。
IIS_IUSRS
似乎没有打印权限,请尝试将 IIS_IUSRS 添加到打印操作员组/向用户授予打印权限。
that's an interesting program.
IIS_IUSRS
seems to have no permission to print, try adding
IIS_IUSRS
to Print Operators Group / grant Print permission to the user.Shell_exec() 几乎用于 shell 命令(ls/dir、cp 等)
您是否尝试过使用 exec() 而不是 shell_exec() ?
Shell_exec() is almost intended for shell commands (ls/dir, cp, etc.)
Have you tried to use exec() instead of shell_exec() ?
感谢大家的评论。不幸的是,这个“php start printjob”是一个更大项目的一部分,今天被取消了,因为,嗯……我不知道……政治原因。我猜这个项目几乎已经死了。
不管怎样,我在过去的几天里又尝试了几次,但无法让它与 IIS 一起工作。我已经实现并测试过的解决方案:删除 IIS,使用本地 apache 安装 XAMPP 或 WAMPP 包以及以管理员访问权限运行的 PHP。
这成功了。我在 PHP 中使用了
pclose(popen('...command...', 'r'));
来启动.exe
,这样 PHP 就可以执行不用等到 PDF 完成。一切都很好。这是我的 C# 代码,它使用 Acrobat Reader 启动打印作业。
第一个参数是应打印的 PDF 的路径,第二个参数是
AcroRd32.exe
的绝对路径。剩下的唯一问题是
AcroRd32.exe
已启动、打印并且再也没有关闭。因此,每个打印作业都会启动一个新的AcroRd32.exe
实例(我使用的是 Acrobat Reader 9.0)。因此,如果打印 10 次,则会创建 10 个 acrobat reader 实例。我所做的是启动打印作业,然后等待 X 秒,希望打印机完成,然后杀死所有
AcroRd32.exe
实例:效果非常好。
请注意,上述操作(杀死所有
AcroRd32.exe
并使用管理员权限运行 PHP)之所以可行,是因为: 整个系统一次只能由一个用户使用,并且区域非常有限使用。它应该用在客户端 POS 上部署的触摸屏应用程序上。销售员会使用 PHP 应用程序来配置产品,然后 PHP 会调用我的 .exe,它会在后台创建并打印 PDF。然后将打印的文档交给客户。 因此,在这种情况下,安全性等并不是真正的问题。
如果有人有解决方案以便将其与 IIS 一起使用,我仍然愿意接受它作为答案。 >
Thanks all for your comments. Unfortunately this "php start printjob" thing was part of a larger project that was cancelled today because of, well... I dont know... political reasons. Guess the project is pretty much dead.
Anyway, I tried myself a few more times in the last days and could not get it to work with IIS. My solution that I implemented and tested already: remove IIS, install a XAMPP or WAMPP package with a local apache and PHP that runs with admin access rights.
This did the trick. I used
pclose(popen('...command...', 'r'));
in PHP in order to start the.exe
and so that PHP does not wait until the PDF is finished. It all worked great.Here is my C# code which starts the print job using Acrobat Reader
The first argument is the path to the PDF that should be printed, the second parameter is the absolute path to the
AcroRd32.exe
.The only problem left was that
AcroRd32.exe
was started, printed and never got closed again. So every printjob started a new instance ofAcroRd32.exe
(I am using Acrobat Reader 9.0). So if you printed 10 times, 10 acrobat reader instances were created.What I did was starting the print job, then waiting X seconds, hoping that the printer was finished and then killing all
AcroRd32.exe
instances:This worked out quite well.
Note that the above (killing all
AcroRd32.exe
and running PHP with admin privilegs) was only doable because: The whole thing is only used by one user at a time and has a very limited area of use.It should be used on a touchscreen application deployed at the clients POS. A salesman would use the PHP app in order to configure a product, and then PHP would call my .exe which would create and print a PDF in the background. The printed document is then handed to the client. So security etc. was not really a concern in this case.
If anyone has a solution in order to use it with IIS, I am still willing to accept it as an answer.