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