Как я могу отправить факс для pdf из службы Windows, используя FAXCOMEXLib?

Я видел этот вопрос, заданный ранее, но я не видел никаких определенных ответов, и определенно нет ответов, которые решают мою проблему. Я создал службу Windows для отправки факсов (полуавтоматически) с использованием библиотеки FAXCOMEXLib. До сих пор мой сервис успешно отправлял текстовые файлы (.txt). Но когда я пытаюсь отправить pdf, jpg или tif файлы, я получаю ошибку "Операция не удалась". В SO я видел много дискуссий о правах пользователя, под которым работает служба. Я пробовал много разных опций (локальный сервис, локальный пользователь, пользователь с правами администратора, разрешить сервису взаимодействовать с рабочим столом). Но ничто, кажется, не имеет значения. Похоже, что у службы нет прав на открытие соответствующего приложения для "печати" файла pdf, jpg или tif. Но я только размышляю. Кому-нибудь удалось отправить факс через FAXCOMEXLib в службе Windows? Вот мой код, который отправляет факс:

fileName = @"D:\temp\FaxTest.txt"; //THIS WORKS
//fileName = @"D:\temp\FaxTest.pdf"; //Operation failed
//fileName = @"D:\temp\FaxTest.tif"; //Operation failed
faxDoc.Sender.Name = faxRec.From;
faxDoc.Sender.Company = faxRec.From;
faxDoc.Body = fileName;
faxDoc.Subject = faxRec.ReferenceId;
faxDoc.DocumentName = faxRec.ReferenceId;
var to = "xxxxxxxxxx";
faxDoc.Recipients.Add(to, "Some Name");
var serverName = Environment.MachineName;
string[] returnVal = faxDoc.Submit(serverName);

Если вам интересно, да, эти файлы существуют на сервере с такими именами, и они являются действительными файлами (я могу открыть их в Adobe Reader и Picture Viewer). И это также прекрасно работает, если я запускаю это локально на моей машине разработчика. И, конечно же, перед отправкой всплывает соответствующий просмотрщик (на моей локальной машине). Я предполагаю, что по какой-то причине сервис не может открыть зрителя. Кто-нибудь успешно отправлял PDF-файл таким образом в службу Windows?

3 ответа

Решение

Я хочу дать полный ответ на это. В ранее опубликованных ответах были некоторые решения, но они не дали полной картины всего, что мы должны были сделать, чтобы успешно отправить файл PDF через линию факса, используя FAXCOMEXLib в нашей пользовательской службе Windows.

Я хочу начать с того, что FAXCOMEXLib создан для консольного приложения Windows, а не для службы Windows. Вы даже можете прочитать это в документации. И я думаю, именно поэтому у нас было так много проблем, чтобы заставить его работать.

Тем не менее, мы смогли заставить его работать (наконец-то) после долгих проб и ошибок. Большинство проблем, с которыми мы столкнулись, были связаны с настройкой и разрешениями в Adobe Reader. Мы обнаружили, что Adobe Reader при обработке файла PDF пытался сделать много чего-то скрытого. И те "вещи", которые он пытался сделать, требовали взаимодействия с пользователем (щелкнув окнами оповещений и т. Д.). При запуске этой службы в службе Windows пользователь не взаимодействует с этой службой, что привело к зависанию нашего процесса на неопределенное время и в конечном итоге к ошибке. Но мы обнаружили, что есть способ обойти это. Вот как мы это сделали:

Вот фрагмент кода, который мы используем, который работает:

fileName = @"D:\temp\FaxTest.pdf";
faxDoc.Sender.Name = faxRec.From;
faxDoc.Sender.Company = faxRec.From;
faxDoc.Body = fileName;
faxDoc.Subject = faxRec.ReferenceId;
faxDoc.DocumentName = faxRec.ReferenceId;
var to = "xxxxxxxxxx";
faxDoc.Recipients.Add(to, "Some Name");
var serverName = Environment.MachineName;
var myProcesses = Process.GetProcessesByName("AcroRd32");
foreach (var myProcess in myProcesses)
{
    if (DateTime.Now.Ticks - myProcess.StartTime.Ticks > TimeSpan.FromSeconds(30).Ticks) {
        myProcess.Kill();
    }
}
string[] returnVal = faxDoc.Submit(serverName);

Конечно, в нашем сервисе больше кода, чем этого. Другой код выполняет такие вещи, как обработка обработчиков событий обратного вызова для отслеживания состояния отправленных / завершенных / неудачных факсов и т. Д. Но это "сердце" кода, которое фактически инициирует "отправку".

И вот список изменений конфигурации, которые мы внесли на сервер, чтобы наша служба Windows правильно декодировала, отображала и отправляла файлы PDF в виде факсов. Некоторые из них перечислены в некоторых ответах, но некоторые нет, и я хотел, чтобы это был полный ответ.

  1. Войдите на сервер как администратор и установите роль сервера факсов на сервере.
  2. Убедитесь, что устройство / карта факс-модема правильно установлены на сервере и что линия факса активна. Вы можете просто попробовать отправить пару тестовых факсов с текстовыми файлами прямо из утилиты Windows Fax. (В нашем случае мы столкнулись с проблемами, потому что нам нужно было набрать "9" и секретный пароль, чтобы получить внешнюю линию междугородной связи).
  3. Установите Adobe Reader на сервер.
  4. Создайте пользователя на сервере, чтобы ваша служба Windows запускалась "как". Мы позвонили нашему пользователю "FaxServiceUser".
  5. Войдите на сервер как данный FaxServiceUser хотя бы один раз. После входа в систему установите устройство "Adobe PDF" в качестве принтера по умолчанию.
  6. Также, войдя в систему как этот пользователь, откройте PDF-файл с помощью Adobe и щелкните по лицензионному соглашению.
  7. Когда вы вошли в систему как этот пользователь и пока у вас открыт Adobe Reader, измените эти настройки:
    • Если установлен этот флажок, снимите флажок "Показывать мне сообщения при запуске Reader" (в разделе "Общие").
    • Снимите флажок "Включить защищенный режим" при запуске (это может относиться только к Acrobat 10. В Acrobat 11 этот параметр был перемещен в "Безопасность" (расширенный) и называется "Включить защищенный режим при запуске". Просто убедитесь, что отметьте эту опцию)
    • Снимите флажок "Включить усиленную безопасность" (в разделе "Безопасность (усиленная)" - это может относиться только к Acrobat 11 и более поздним версиям).
    • Выберите опцию "Обновление" и отключите автоматическую загрузку и установку обновлений.
    • Снимите флажок "Создать ссылки из URL" (в разделе "Общие").
    • Снимите флажок "Make Hand tool читать статьи" (в разделе "General")
    • Снимите флажок "Показывать мне сообщения при запуске Reader" (в разделе "Общие")
    • Снимите флажок "Автоматически вычислять значения полей" (в разделе "Формы").
    • Снимите флажок "Показывать прямоугольники фокуса" (в разделе "Формы").
    • Снимите флажок "Показывать индикатор переполнения текстового поля" (в разделе "Формы")
    • Снимите флажок "Включить Acrobat JavaScript" (в разделе "Javascript").
    • Снимите флажок "Показать диалог приветствия" (в разделе "Просмотр")
    • Снимите флажок "Показывать предупреждение о подключении к серверу при открытии файла" (в разделе "Просмотр")
  8. При необходимости обратитесь по этой ссылке за помощью в настройках Adobe Reader: http://kb.faxback.com/How+To+Configure+Adobe+XI+for+Use+with+NET+SatisFAXtion
  9. После сборки, развертывания и установки службы Windows измените свойства службы так, чтобы она работала "как" пользователем, которого вы создали ранее (в нашем случае "FaxServiceUser").
  10. Добавьте разрешения для этого FaxServiceUser к любой из папок, которые ему нужны для чтения / записи / удаления из / в.
  11. Поскольку Adobe предназначена для запуска в качестве настольного приложения, добавьте некоторый код в свой сервис, чтобы освободить память, используемую Adobe Reader (Вы можете увидеть, как мы сделали это в myProcess.Kill() функция в примере кода).

И это должно сделать это. Это немного громоздко, но я надеюсь, что это дает полный пример того, как настроить Adobe Reader в сочетании с вашей пользовательской службой Windows для отправки факсов из файлов PDF на сервер Windows. Мы занимаемся этим уже пару месяцев без проблем. Наш клиент делает небольшое количество факсов, поэтому я не могу говорить о том, как это работает с большим количеством факсов. Так что, если вы ищете "бесплатный" способ отправки факсов, не платя за что-то вроде Интерфакса, это может быть жизнеспособным вариантом, по крайней мере, для малой громкости.

Это хорошо документировано в статье MSDN. Нетривиальная вещь, которая должна произойти, состоит в том, что некоторые программы должны преобразовывать содержимое файла в печатный текст, который можно отправить по факсу. Цитирование:

Примерами документов, которые можно отправлять в качестве тела факса, являются текстовый файл (.txt), документ Microsoft Word (.doc) или электронная таблица Microsoft Excel (.xls). Когда вы отправляете факс с клиентского компьютера, тело должно быть связано с приложением, которое установлено на этом компьютере, и приложение должно поддерживать глагол PrintTo; в противном случае факс не удастся.

Итак, один простой тест, который вы можете сделать, это щелкнуть правой кнопкой мыши файл в проводнике и найти команду "Печать". Затем перетащите файл на принтер, чтобы применить глагол PrintTo. Если этот тест не пройден, он не будет работать, и вам нужно установить приложение, которое знает, как распечатать файл.

Выполнение этого из службы предъявляет дополнительные требования к приложению, которое выполняет печать. Многие из них не очень хорошо себя ведут в сервисе. Особенно, когда вы пытаетесь печатать, Microsoft настоятельно рекомендует никогда не делать этого в службе. Например, в последнее время офисные приложения этого не делают, что делает совет MSDN слабым соусом.

На моей машине расширение.tif связано с приложением UWP, которое также не будет работать в службе. Дать хороший совет сложно, учитывая большое количество приложений, которые работают с этими популярными расширениями, лучше всего зайти на superuser.com и назвать конкретное расширение, версию Windows и приложение, которое вы предпочитаете использовать. Делать это из пользовательского сеанса, безусловно, наименее хлопотно.

Эта проблема, по-видимому, связана с процессом с именем "AcroRd32", который открывает факс в Acrobat Reader и преобразует его в файл TIFF перед отправкой. Этот процесс не освобождает память.

Попробуйте остановить процесс следующим образом

Dim myProcesses() As Process Dim myProcess As Process
' How to retrieve the program associat with pdf, when i only know the file extension ?
myProcesses = Process.GetProcessesByName("AcroRd32") For Each myProcess In myProcesses
If Date.Now.Ticks - myProcess.StartTime.Ticks > TimeSpan.FromSeconds(30).Ticks Then
myProcess.Kill()
End If
Next

Я надеюсь, что это полезно.

Я также хотел отправить факс через службу Windows с помощью faxcomexlib, но после исследования я понял, что эта библиотека Windows не может использоваться в службе, и я понял это с помощью монитора процесса, потому что решил использовать факс-сервер. Чтобы создать файл.exe и вызвать его из службы и отправить ему нужные аргументы, тогда у меня была проблема сеанса при вызове процесса через службу Windows, затем я решил эту проблему и теперь отправляю факс через Windows Служба легко сделанный.

Другие вопросы по тегам