这很可能不是一件容易的事,但情况如下:
我编写了一个C#命令行应用程序:
Acrord32.exe
使用System.Diagnostics.Process
(这是Acrobat Reader)以静默打印生成的PDF 如果我构建我的解决方案并双击pdfGen.exe
,它会按预期工作。 PDF已创建并打印。
现在,我的应用程序必须部署在运行IIS 7的Windows Vista的内部服务器上。此服务器运行一些PHP webapp。它将通过PHP使用shell_exec()
调用,以便生成的PDF将打印在连接到服务器的打印机上。
所以我的PHP页面看起来基本上是这样的:
shell_exec('/path/to/pdfGen.exe');
但这里出了问题。根据任务经理等情况会发生什么:
pdfGen.exe
开始Acrord32.exe
开始pdfGen.exe
永远挂起(PHP脚本也是如此)并且没有打印任何内容我很确定这是与权限相关的问题。我已经IIS_IUSRS
访问了默认打印机,并且访问了Acrord32.exe
所在的目录。但是,仍然没有打印。但是,如果我手动启动我的pdfGen.exe它可以工作。
知道我错过了什么吗?
编辑:
我不一定要使用Acrobat Reader来打印PDF。如果还有另一种方式静默打印创建的PDF服务器端,我根本不介意。
答案 0 :(得分:1)
为了检查发生了什么,请尝试运行 process monitor from Sysinternals并将事件过滤到adobe acrobat流程。您将看到acrobat的系统调用,它将让您了解更多或更少的错误。
答案 1 :(得分:1)
我知道您的解决方案有一点改进:SumatraPDF有一个很好的命令行界面,可用于在打印后自动关闭Sumatra。
我使用PHP“system”或“exec”函数执行批处理文件以打开SumatraPDF:
sumatrapdf.exe -print-to-default -exit-on-print <path_to_PDF_file>
(您也可以指定要打印的打印机名称)
答案 2 :(得分:0)
这是一个有趣的节目。
IIS_IUSRS
似乎没有打印权限,请尝试将IIS_IUSRS
添加到Print Operators Group /授予用户打印权限。
答案 3 :(得分:0)
Shell_exec()几乎用于shell命令(ls / dir,cp等) 您是否尝试使用exec()而不是shell_exec()?
答案 4 :(得分:0)
感谢大家的评论。不幸的是,这个“php start printjob”的东西是今天取消的一个更大的项目的一部分,因为,好吧......我不知道......政治原因。猜猜这个项目已经死了。
无论如何,我在最后几天尝试了几次,但是无法让它与IIS一起工作。我已经实现并测试过的解决方案:删除IIS,安装带有本地apache的XAMPP或WAMPP包以及使用 admin访问权限运行的PHP。
这就是诀窍。我在PHP中使用了pclose(popen('...command...', 'r'));
来启动.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
已启动,打印并且再也没有关闭过。所以每个printjob都启动了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中使用它,我仍然愿意接受它作为答案。