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

How can I send a fax for a pdf from a Windows Service using FAXCOMEXLib?

我以前看过这个问题,但我没有看到任何明确的答案,更没有任何答案可以解决我的问题。我创建了一个 windows 服务来使用 FAXCOMEXLib 库发送传真(半自动)。到目前为止,我的服务已成功发送文本文件 (.txt)。但是当我尝试发送 pdf、jpg 或 tif 文件时,我收到“操作失败”错误。在 SO 中,我看到了很多关于服务 运行ning 下的用户权限的讨论。我尝试了很多不同的选项(本地服务、本地用户、具有管理员权限的自定义用户、允许服务与桌面交互)。但似乎没有什么不同。该服务似乎没有权限打开相应的应用程序来“打印”pdf、jpg 或 tif 文件。但我只是猜测。有没有人在 Windows 服务中通过 FAXCOMEXLib 成功发送传真?这是我发送传真的代码:

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);

如果您想知道,是的,这些文件确实以这些名称存在于服务器上,并且它们是有效文件(我可以在 Adob​​e Reader 和图片查看器中打开它们)。如果我在我的开发机器上本地 运行 这也很好用。当然,适当的查看器会在发送前弹出(在我的本地机器上)。我的猜测是由于某种原因该服务无法打开查看器。有没有人在 Windows 服务中以这种方式成功发送 PDF?

问题似乎与名为 "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

希望对您有所帮助。

它在 the MSDN article 中有很好的记录。需要发生的重要事情是 some 软件需要将文件内容转换为可以传真的可打印文本。引用:

Examples of documents that you can send as a fax body are a text file (.txt), a Microsoft Word document (.doc), or a Microsoft Excel spreadsheet (.xls). When you send a fax from a client computer, the body has to be associated with an application that is installed on that computer, and the application has to support the PrintTo verb; otherwise, the fax will fail.

因此,您可以做的一个简单测试是在资源管理器中右键单击该文件并查找 "Print" 命令。接下来将文件拖到打印机以使用 PrintTo 动词。如果这些测试失败,那么它将无法正常工作,您需要安装一个知道如何打印文件的应用程序。

通过服务执行此操作会对执行打印的应用程序提出额外要求。其中有很多在服务中表现得不是特别好。特别是当您尝试打印时,Microsoft 强烈建议永远不要在服务中这样做。例如,Office 应用程序最近没有更新,这使得 MSDN 的建议已经很弱了。

在我的机器上,.tif 扩展名与 UWP 应用相关联,该应用也无法在服务中运行。鉴于处理这些流行扩展程序的大量应用程序很难提供好的建议,最好转到 superuser.com 并命名特定扩展程序、Windows 版本和您喜欢使用的应用程序。从用户会话中执行此操作肯定是最不麻烦的。

我想对此给出一个完整的答案。之前发布的答案有一些解决方案,但它们没有完整描述我们在自定义 Windows 服务中使用 FAXCOMEXLib 通过传真线成功发送 pdf 文件所必须做的一切。

首先我想说 FAXCOMEXLib 是为 windows 控制台应用程序而不是 windows 服务制作的。您甚至可以在文档中阅读此内容。我认为这就是为什么我们在让它工作时遇到了很多麻烦。

但是,经过反复试验,我们(最终)能够让它工作。我们遇到的大多数问题都与 Adob​​e Reader 中的设置和权限有关。我们发现 Adob​​e Reader 在处理 PDF 文件时试图在幕后做很多事情。而那些 "things" 它试图进行所需的用户交互(点击警告框等)。当 运行 在 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);

当然,我们的服务中还有比这更多的代码。其他代码执行诸如处理回调事件处理程序以跟踪 sending/completed/failed 传真状态等的事情。但这是实际启动 "send".[=13= 的代码的 "heart" ]

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

  1. 以管理员身份登录服务器并在服务器上安装传真服务器角色。
  2. 确保传真调制解调器 device/card 已正确安装在服务器上,并且传真线路处于活动状态。您可以尝试直接从 Windows 传真实用程序发送几份带有文本文件的测试传真。 (在我们的例子中,我们 运行 遇到了问题,因为我们必须拨“9”和一个秘密 pass-code 才能接通外部 long-distance 线路)。
  3. 在服务器上安装 Adob​​e Reader。
  4. 在服务器上为您的 Windows 服务创建一个用户 运行 "as"。我们打电话给我们的用户 "FaxServiceUser".
  5. 至少以该 FaxServiceUser 身份登录服务器一次。登录后,将 "Adobe PDF" 设备设置为默认打印机。
  6. 同时以该用户身份登录,使用 Adob​​e 打开 PDF 文件并单击 EULA。
  7. 以该用户身份登录并打开 Adob​​e Reader,更改这些设置:
    • 如果选中,un-check "Show me messages when I launch Reader"(在 "General" 下)
    • Un-check "Enable Protected Mode" at startup 复选框(这可能仅适用于 Acrobat 10。在 Acrobat 11 中,此选项已移至“安全性(增强)”并且标题为“启动时启用保护模式” . 只要确保你 un-check 这个选项)
    • Un-check "Enable Enhanced Security"(在 "Security(Enhanced)" 下 - 这可能仅适用于 Acrobat 11 及更高版本)
    • Select 更新程序选项并禁用自动下载和安装更新。
    • Un-check"Create links from URLs"(下"General")
    • Un-check"Make Hand tool read articles"(下"General")
    • Un-check"Show me messages when I launch Reader"(下"General")
    • Un-check"Automatically calculate field values"(下"Forms")
    • Un-check"Show focus rectangles"(下"Forms")
    • Un-check"Show text field overflow indicator"(下"Forms")
    • Un-check"Enable Acrobat JavaScript"(下"Javascript")
    • Un-check"Show welcome dialog"(下"Reviewing")
    • Un-check"Show server connection warning dialog when opening file"(下"Reviewing")
  8. 如有需要,请参阅此 link 以获得有关 Adob​​e Reader 设置的帮助:http://kb.faxback.com/How+To+Configure+Adobe+XI+for+Use+with+NET+SatisFAXtion
  9. 构建、部署和安装 Windows 服务后,将服务的属性更改为 运行 "as" 您之前创建的用户("FaxServiceUser" 在我们的例)。
  10. 将该 FaxServiceUser 添加到它需要的任何文件夹的权限 read/write/delete from/to。
  11. 由于 Adob​​e 旨在 运行 作为桌面应用程序,因此请在您的服务中添加一些代码以释放 Adob​​e Reader 使用的内存(您可以在 myProcess.Kill()示例代码中的函数)。

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

我也想通过 Windows 服务使用 faxcomexlib 发送传真,但经过研究,我意识到这个 Windows 库在服务中不可用,我使用进程监视器,因为我决定使用传真服务器。要创建一个 .exe 文件并从服务调用它并向它发送所需的参数,然后我在通过 Windows 服务调用该过程时遇到会话问题,然后我解决了这个问题,现在通过 Windows服务很简单