通过PHP启动服务器端的打印作业

这很可能不是一件容易的事情,但现在是这样的情况:

我写了一个C#命令行应用程序,其中:

  • 使用ITextSharp创buildPDF
  • 把它写入磁盘
  • 通过System.Diagnostics.Process使用Acrord32.exe (这是Acrobat Reader),以便静默地打印生成的PDF

如果我构build我的解决scheme并双击pdfGen.exe ,它按预期工作。 PDF被创build和打印。

现在,我的应用程序必须部署在运行IIS 7的Windows Vista的内部服务器上。此服务器正在运行一些PHP webapp。 它将通过使用shell_exec()通过PHP调用,以便生成的PDF将打印在连接到服务器的打印机上。

所以我的PHP页面看起来基本上是这样的:

 shell_exec('/path/to/pdfGen.exe'); 

但是这里出了问题。 根据任务经理等发生的情况

  • pdfGen.exe启动
  • PDF被创build
  • Acrord32.exe启动
  • pdfGen.exe永远挂起(PHP脚本也是这样)并且什么都不打印

我很确定这是一些权限相关的问题 。 我已经给IIS_IUSRS访问默认打印机,并Acrord32.exe所在的目录。 但是,仍然没有印刷。 但是,如果我手动启动我的pdfGen.exe它的作品。

任何想法我失踪?

编辑:

我不打算使用Acrobat Reader来打印PDF。 如果还有另一种方式来悄悄地打印创build的PDF服务器端,我根本不介意。

Solutions Collecting From Web of "通过PHP启动服务器端的打印作业"

为了检查发生了什么,尝试从Sysinternals运行进程监视器,并将事件过滤到adobe acrobat进程。 你会看到acrobat系统调用,它会让你知道或多或少出了什么问题。

我知道你的解决方案有一点改进:SumatraPDF有一个很好的命令行界面,可以用来在打印后自动关闭苏门答腊。

我使用PHP“系统”或“执行”功能来执行一个批处理文件来打开SumatraPDF:

 sumatrapdf.exe -print-to-default -exit-on-print <path_to_PDF_file> 

(您也可以指定要打印的打印机名称)

这是一个有趣的程序。

IIS_IUSRS似乎没有权限打印,请尝试将IIS_IUSRS添加到打印操作员组/授予打印权限给用户。

Shell_exec()几乎用于shell命令(ls / dir,cp等)您是否尝试使用exec()而不是shell_exec()?

谢谢大家的意见。 不幸的是,这个“php开始printjob”的东西是一个更大的项目,因为今天取消的一部分,呃…我不知道……政治原因。 猜猜这个项目已经死了。

无论如何,我在最后几天尝试了几次,并且无法使用IIS。 我已经实现和测试的解决方案:删除IIS,安装一个XAMPP或WAMPP包与本地apache和PHP运行与管理员访问权限

这个伎俩。 我用pclose(popen('...command...', 'r')); 在PHP中,以启动.exe并使PHP不会等到PDF完成。 这一切都很好。

这是我的C#代码,它使用Acrobat Reader启动打印作业

 public void Print(string pathname, string acrobatDirectory) { var proc = new Process { StartInfo = { Arguments = String.Format("/t \"{0}\"", pathname), FileName = acrobatDirectory, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = false, RedirectStandardError = false, } }; proc.Start(); } 

第一个参数是应该打印的PDF的路径,第二个参数是AcroRd32.exe的绝对路径。

剩下的唯一问题就是AcroRd32.exe已经启动,打印并且再也不能关闭了。 所以每个打印作业都启动了一个AcroRd32.exe的新实例(我正在使用Acrobat Reader 9.0)。 因此,如果您打印10次,则会创建10个acrobat reader实例。

我所做的是开始打印作业,然后等待X秒钟,希望打印机完成,然后杀死所有AcroRd32.exe实例:

 public void Print(string pathname, string acrobatDirectory) { Debug.WriteLine("Printing..."); Printer.Print(pathname, acrobatDirectory); Thread.Sleep(30000); try { Debug.WriteLine("Trying to kill runnung AcroRd32.exe's "); FindAndKillProcess("AcroRd32"); } catch (Exception) { Debug.WriteLine("AcroRd32.exe could not be killed..."); } } private bool FindAndKillProcess(string name) { foreach (Process clsProcess in Process.GetProcesses()) { if (clsProcess.ProcessName.StartsWith(name)) { clsProcess.Kill(); return true; } } return false; } 

这工作得很好。


请注意,上述(杀死所有AcroRd32.exe和运行具有管理员权限的PHP)只能执行,因为: 整个事件一次只能由一个用户使用,并且使用面积非常有限

它应该用于在客户端POS部署的触摸屏应用程序。 推销员将使用PHP应用程序来配置一个产品,然后PHP会调用我的.exe,这将创建并在后台打印PDF。 打印的文件然后交给客户。 所以在这种情况下,安全等并不是真正的问题。


如果任何人有一个解决方案,以使用IIS,我仍然愿意接受它作为答案。