如何使用FAXCOMEXLib从Windows服务发送pdf传真?

Mat*_*nks 16 c# windows-services fax interfax

我之前看到过这个问题,但我没有看到任何明确的答案,绝对没有任何答案可以解决我的问题.我创建了一个Windows服务,使用FAXCOMEXLib livrary发送传真(半自动).到目前为止,我的服务已成功发送文本文件(.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);
Run Code Online (Sandbox Code Playgroud)

如果您想知道,是的,那些文件确实存在于具有这些名称的服务器上,并且它们是有效文件(我可以在Adobe Reader和Picture Viewer中打开它们).如果我在我的开发机器上本地运行它,这也可以正常工作.当然,在发送之前(在我的本地机器上)弹出适当的查看器.我的猜测是,由于某种原因,该服务无法打开查看器.有没有人成功地在Windows服务中以这种方式发送PDF?

Mat*_*nks 3

我想对此给出一个完整的答案。之前发布的答案提供了一些解决方案,但它们并未全面介绍我们在自定义 Windows 服务中使用 FAXCOMEXLib 通过传真线路成功发送 pdf 文件所需执行的所有操作。

我想首先说 FAXCOMEXLib 是为 Windows 控制台应用程序而不是 Windows 服务而设计的。您甚至可以在文档中阅读这一点。我认为这就是为什么我们在让它发挥作用时遇到如此大的困难。

然而,经过多次尝试和错误,我们(最终)能够让它发挥作用。我们遇到的大多数问题都与 Adob​​e Reader 中的设置和权限有关。我们发现 Adob​​e 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);
Run Code Online (Sandbox Code Playgroud)

当然,我们的服务中还有比这更多的代码。其他代码执行诸如处理回调事件处理程序以跟踪发送/完成/失败传真的状态等操作。但这是实际启动“发送”的代码的“核心”。

以下是我们对服务器所做的配置更改列表,以使我们的自定义 Windows 服务正确解码、渲染并将 pdf 文件作为传真发送。其中一些已在某些答案中列出,但有些则没有,我希望这是一个完整的答案。

  1. 以管理员身份登录服务器并在服务器上安装传真服务器角色。
  2. 确保传真调制解调器设备/卡已正确安装在服务器上,并且传真线路处于活动状态。您可能只是尝试直接从 Windows 传真实用程序发送几个带有文本文件的测试传真。(在我们的例子中,我们遇到了问题,因为我们必须拨打“9”和秘密密码才能拨打外部长途电话线)。
  3. 在服务器上安装 Adob​​e Reader。
  4. 在服务器上创建一个用户,以便 Windows 服务以“as”运行。我们将用户称为“FaxServiceUser”。
  5. 以该 FaxServiceUser 身份登录服务器至少一次。登录后,将“Adobe PDF”设备设置为默认打印机。
  6. 此外,以该用户身份登录后,使用 Adob​​e 打开 PDF 文件并单击 EULA。
  7. 以该用户身份登录并打开 Adob​​e Reader 后,更改以下设置:
    • 如果选中,请取消选中“启动阅读器时显示消息”(在“常规”下)
    • 取消选中“启动时启用保护模式”复选框(这可能仅适用于 Acrobat 10。在 Acrobat 11 中,此选项已移至“安全性(增强)”,标题为“启动时启用保护模式”。只需确保您取消选中“启动时启用保护模式”复选框即可。检查这个选项)
    • 取消选中“启用增强安全性”(在“安全性(增强)”下 - 这可能仅适用于 Acrobat 11 及更高版本)
    • 选择更新程序选项并禁用自动下载和安装更新。
    • 取消选中“从 URL 创建链接”(在“常规”下)
    • 取消选中“使手工具读取文章”(在“常规”下)
    • 取消选中“启动阅读器时显示消息”(在“常规”下)
    • 取消选中“自动计算字段值”(在“表单”下)
    • 取消选中“显示焦点矩形”(在“表单”下)
    • 取消选中“显示文本字段溢出指示器”(在“表单”下)
    • 取消选中“启用 Acrobat JavaScript”(在“Javascript”下)
    • 取消选中“显示欢迎对话框”(在“审阅”下)
    • 取消选中“打开文件时显示服务器连接警告对话框”(在“审阅”下)
  8. 如果需要,请查阅此链接以获取有关 Adob​​e Reader 设置的帮助:http://kb.faxback.com/How+To+Configure+Adobe+XI+for+Use+with+NET+SatisFAXtion
  9. 构建、部署和安装 Windows 服务后,更改服务的属性以“作为”您之前创建的用户(在我们的示例中为“FaxServiceUser”)运行。
  10. 将该 FaxServiceUser 的权限添加到它需要读取/写入/删除的任何文件夹。
  11. 由于 Adob​​e 旨在作为桌面应用程序运行,因此请在您的服务中添加一些代码以释放 Adob​​e Reader 使用的内存(您可以在myProcess.Kill()示例代码的函数中看到我们是如何做到这一点的)。

那应该可以了。这有点麻烦,但我希望这提供了一个完整的示例,说明如何将 Adob​​e Reader 与自定义 Windows 服务结合使用,以从 Windows 服务器上的 pdf 文件发送传真。我们已经这样做了几个月了,没有任何问题。我们的客户处理的传真量很少,因此我无法说明这如何处理大量的传真。因此,如果您正在寻找一种“免费”发送传真的方式,而无需支付 Interfax 之类的费用,那么这可能是一个可行的选择,至少对于低容量而言。