c#使用FAXCOMEXLib发送传真的流程以及容易出现的问题

服务运行环境 windows server2019,开发工具VS2022

1. 配置fax服务,勾上图中的选项

 

 

 

2. 项目属性-》添加com引用-》选择Microsoft Fax Service,这里一定要注意,f 开头的两个版本不对,一定要引用M开头的版本

 

 

 

 

 3.发送传真的具体方法

       //自定义发送类,并初始化,Connect方法参数传空,表示使用本地连接的传真机器,本项目中连的是传真猫
public
FaxSender() { try { faxServer = new FaxServer(); faxServer.Connect(""); RegisterFaxServerEvents(); } catch (Exception ex) { logger.Error(ex, "Error connecting to fax server"); } }
        // 注册传真发送事件监听
private void RegisterFaxServerEvents() { faxServer.OnOutgoingJobAdded += new IFaxServerNotify2_OnOutgoingJobAddedEventHandler(faxServer_OnOutgoingJobAdded); faxServer.OnOutgoingJobChanged += new IFaxServerNotify2_OnOutgoingJobChangedEventHandler(faxServer_OnOutgoingJobChanged); faxServer.OnOutgoingJobRemoved += new IFaxServerNotify2_OnOutgoingJobRemovedEventHandler(faxServer_OnOutgoingJobRemoved); var eventsToListen = FAX_SERVER_EVENTS_TYPE_ENUM.fsetFXSSVC_ENDED | FAX_SERVER_EVENTS_TYPE_ENUM.fsetOUT_QUEUE | FAX_SERVER_EVENTS_TYPE_ENUM.fsetOUT_ARCHIVE | FAX_SERVER_EVENTS_TYPE_ENUM.fsetQUEUE_STATE | FAX_SERVER_EVENTS_TYPE_ENUM.fsetACTIVITY | FAX_SERVER_EVENTS_TYPE_ENUM.fsetDEVICE_STATUS; faxServer.ListenToServerEvents(eventsToListen); }
        //监听事件触发的自定义处理事件
#region
Event Listeners private static void faxServer_OnOutgoingJobAdded(FaxServer pFaxServer, string bstrJobId) { logger.Info("OnOutgoingJobAdded event fired. A fax is added to the outgoing queue."); } private static void faxServer_OnOutgoingJobChanged(FaxServer pFaxServer, string bstrJobId, FaxJobStatus pJobStatus) { logger.Info("OnOutgoingJobChanged event fired. A fax is changed to the outgoing queue."); pFaxServer.Folders.OutgoingQueue.Refresh(); PrintFaxStatus(pJobStatus); } private static void faxServer_OnOutgoingJobRemoved(FaxServer pFaxServer, string bstrJobId) { logger.Info("OnOutgoingJobRemoved event fired. Fax job is removed to outbound queue."); } #endregion private static void PrintFaxStatus(FaxJobStatus faxJobStatus) { if (faxJobStatus.ExtendedStatusCode == FAX_JOB_EXTENDED_STATUS_ENUM.fjesDIALING) { logger.Info("Dialing..."); } if (faxJobStatus.ExtendedStatusCode == FAX_JOB_EXTENDED_STATUS_ENUM.fjesTRANSMITTING) { logger.Info("Sending Fax..."); } if (faxJobStatus.Status == FAX_JOB_STATUS_ENUM.fjsCOMPLETED && faxJobStatus.ExtendedStatusCode == FAX_JOB_EXTENDED_STATUS_ENUM.fjesCALL_COMPLETED) { logger.Info("Fax is sent successfully."); } }

 

重点来了,发送传真到传真服务器的方法

        /// <summary>
        /// 发送传真的方法
        /// </summary>
        /// <param name="body">是一个要传真的文件路径</param>
        /// <param name="faxMessage">自定义model,这里用到sender(传真发送方,可空)和recipient(传真接收号码)</param>
        /// <param name="subject">传真主题,可空</param>
        /// <param name="docName">文件名,可空</param>
        public void SendFax(string body, FaxMessage faxMessage, string subject = null, string docName = null)
        {
            try
            {
                logger.Debug("begin FaxDocumentSetup");
                FaxDocumentSetup(subject, docName, body, faxMessage.Sender, faxMessage.Recipient);
                logger.Debug("end FaxDocumentSetup and begin Submit");
                var submitReturnValue = faxDoc.Submit(faxServer.ServerName);//这里返回值应该是传真事件的id,可以用来主动查询传真发送的状态
                logger.Debug($"end Submit,submit result:{JsonConvert.SerializeObject(submitReturnValue)}");
                faxDoc = null;
            }
            catch (Exception comException)
            {
                logger.Error(comException, "Error SendFax to fax server. Error Message: " + comException.Message);
            }
        }

        /// <summary>
        /// 初始化要发送的传真文档
        /// </summary>
        /// <param name="subject"></param>
        /// <param name="docName"></param>
        /// <param name="body"></param>
        /// <param name="sender"></param>
        /// <param name="recipient"></param>
        private void FaxDocumentSetup(string subject, string docName, string body, string sender, string recipient)
        {
            faxDoc = new FaxDocument
            {
                Priority = FAX_PRIORITY_TYPE_ENUM.fptLOW,
                ReceiptType = FAX_RECEIPT_TYPE_ENUM.frtNONE,
                AttachFaxToReceipt = true,
                Body = body,
                Subject = subject ?? body.Substring(0, 1),
                DocumentName = docName ?? body.Substring(0, 1)
            };

            faxDoc.Sender.Name = sender;
            faxDoc.Sender.Company = "";
            faxDoc.Recipients.Add(recipient);
        }

 

注意,上面FaxDocumentSetup方法中,FaxDocument.Priority有三种,如果使用FAX_PRIORITY_TYPE_ENUM.fptHIGH,且项目以windows service方式运行的话,无法打印pdf文件

会报"System.IO.FileLoadException: Operation failed"  "System.UnauthorizedAccessException: Access denied"这两种错误

 

方法使用:直接FaxSender.SendFax 传参就行

 

注意!注意!!注意!!!

本项目测试过传真txt文档,tif图片和pdf文档,其中传真pdf文档最麻烦

传真pdf文档需要电脑上安装pdf viewer,别人有推荐Adobe Acrobat Reader和FoxiReader的,楼主两种都试过,FoxiReader中间出了点问题,最后选择了Adobe Acrobat Reader,估计FoxiReader也是没问题的

如果不安装pdf viewer,会报以下错误"System.Runtime.InteropServices.COMException (0x80070102): Operation failed."

总结起来要传真pdf就是安装pdf viewer,并且faxdocument的Priority使用FAX_PRIORITY_TYPE_ENUM.fptLOW,这里权限还有一种fptNORMAL,有兴趣的可以自行尝试

 

其他的可传真文件类型楼主没有一一尝试,有兴趣的可以自行研究下

 

传送门:

https://docs.microsoft.com/zh-cn/windows/win32/api/faxcomex/ 

https://blog.csdn.net/cunchi8090/article/details/107485727

https://www.codeproject.com/Tips/1041737/Work-with-Fax-Using-FAXCOMEXLib?msg=5477440#xx5477440xx

posted @ 2022-04-22 16:21  along_bro  阅读(424)  评论(0编辑  收藏  举报