Запуск задания печати на сервере через PHP
Вопрос
Скорее всего, это непросто, но вот ситуация:
Я написал приложение командной строки C#, которое:
- создает PDF-файл с помощью ITextSharp
- записывает это на диск
- использует
Acrord32.exe
(это Acrobat Reader) черезSystem.Diagnostics.Process
чтобы бесшумно распечатать сгенерированный PDF-файл
Если я создам свое решение и дважды щелкну по pdfGen.exe
, он работает так, как ожидалось.PDF-файл создается и распечатывается.
Теперь мое приложение необходимо развернуть на внутреннем сервере с Windows Vista и IIS 7.На этом сервере работает веб-приложение PHP.И он будет вызываться через PHP, используя shell_exec()
чтобы полученный 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-файл на сервере, я бы вообще не возражал.
Решение 5
Спасибо всем за ваши комментарии.К сожалению, эта штука «php start printjob» была частью более крупного проекта, который сегодня был отменен из-за, ну...Я не знаю...политические причины.Думаю, проект практически мертв.
В любом случае, за последние дни я попробовал еще несколько раз и не смог заставить его работать с IIS.Мое решение, которое я уже реализовал и протестировал:удалите IIS, установите пакет XAMPP или WAMPP с локальным Apache и PHP, который работает с права доступа администратора.
Это помогло.я использовал pclose(popen('...command...', 'r'));
в PHP, чтобы запустить .exe
и чтобы PHP не ждал завершения PDF-файла.Все сработало отлично.
Вот мой код С#, который запускает задание печати с помощью 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-файлу, который необходимо распечатать, второй параметр — абсолютный путь к 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, я все равно готов принять его в качестве ответа.
Другие советы
Чтобы проверить, что происходит, попробуйте запустить монитор процессов от Sysinternals и отфильтровать события в процессе Adobe Acrobat.Вы увидите системные вызовы Acrobat и это позволит вам более или менее узнать, что происходит не так.
Я знаю небольшое улучшение вашего решения:SumatraPDF имеет приятный интерфейс командной строки, который можно использовать для автоматического закрытия Sumatra после печати.
Я использовал «системные» или «exec» функции 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 ()?