Вопрос

Скорее всего, это непросто, но вот ситуация:

Я написал приложение командной строки 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 ()?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top