Запуск работы с сервером через PHP

Это, скорее всего, нелегко, но вот ситуация:

Я написал приложение командной строки C #, которое:

  • создает PDF-файл с использованием ITextSharp
  • записывает его на диск
  • использует Acrord32.exe (это Acrobat Reader) через System.Diagnostics.Process , чтобы тихо распечатать сгенерированный PDF-файл

Если я pdfGen.exe свое решение и дважды щелкните pdfGen.exe , он будет работать, как ожидалось. PDF создается и печатается.

Теперь мое приложение должно быть развернуто на внутреннем сервере с Windows Vista с IIS 7. На этом сервере работает PHP webapp. И он будет вызван через PHP с помощью shell_exec() чтобы полученный PDF-файл был напечатан на принтере, подключенном к серверу.

Итак, моя страница PHP выглядит в основном так:

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

Но здесь все идет не так. Что происходит в соответствии с диспетчером задач и т. Д .:

  • pdfGen.exe
  • PDF создан
  • Acrord32.exe
  • pdfGen.exe вечно pdfGen.exe (и скрипт PHP), и ничего не печатается

Я уверен, что это проблема, связанная с разрешением . Я уже предоставил IIS_IUSRS доступ к принтеру по умолчанию и директории, в которой находится Acrord32.exe . Но все равно, никакой печати. Однако, если я запускаю файл pdfGen.exe вручную, он работает.

Любая идея, что мне не хватает?

РЕДАКТИРОВАТЬ:

Я не обязан использовать Acrobat Reader для печати PDF. Если есть еще один способ, чтобы тихо напечатать созданный сервер PDF-файлов, я бы совсем не возражал.

Чтобы проверить, что происходит, попробуйте запустить монитор процесса из Sysinternals и отфильтровать события в процессе adobe acrobat. Вы увидите системные вызовы acrobat, и это позволит вам узнать более или менее то, что происходит неправильно.

Я знаю небольшое улучшение вашего решения: SumatraPDF имеет приятный интерфейс командной строки, который можно использовать для автоматического закрытия Sumatra после печати.

Я использовал функции PHP «system» или «exec» для выполнения командного файла для открытия SumatraPDF:

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

(вы также можете указать имя принтера для печати)

это интересная программа.

IIS_IUSRS похоже, нет разрешения на печать, попробуйте добавить IIS_IUSRS в группу «Операторы печати / грант» для печати.

Shell_exec () почти предназначен для команд оболочки (ls / dir, cp и т. Д.). Вы пытались использовать exec () вместо shell_exec ()?

Спасибо всем за ваши комментарии. К сожалению, этот «php start 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 был запущен, напечатан и не был снова закрыт. Поэтому каждый printjob начал новый экземпляр AcroRd32.exe (я использую Acrobat Reader 9.0). Итак, если вы напечатали 10 раз, было создано 10 экземпляров считывателя acrobat.

Я начал запускать задание на печать, а затем ожидал 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, я все равно согласен принять его в качестве ответа.