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