Using FAXCOMEXLib to send a fax in .Net 2005, version 2.0, with a Windows XP computer

Published on
19,853 Points
2 Endorsements
Last Modified:
I finally figured out a combination of things that allow the Microsoft Fax Service COM Type Library to work in ASP.NET.  I just kept trying different things, and finally got it.  If you're having this problem, try the following:

Be sure you have a PDF viewer installed on the computer, for all PDF, FDF types.  You can use FoxIT reader, which is free, or Adobe Acrobat, which is also free.   I personally got it working with Foxit.

You need the Interop library as a reference in your program.  Go to "Add a Reference" to your program, choose the "COM" tab, then look for the following: "Microsoft Fax Service Extended COM Type Library".  It is listed under M for Microsoft, not under F for faxing.  The other library under F is WRONG--do not use this.

Be sure to log on as an administrator account.  We use a domain where I work, and the Domain Admin did NOT work.  The local administrator account seemed to be the only thing I could get to work, no matter what permissions I changed on the fax printer, the directories in question, etc.

I declared by fax server once, as a part of the class.  See below:

    public class NightlyInvoiceCreditFaxWorkerProgram
        private FAXCOMEXLib.FaxServer _faxServer = new FaxServerClass();
        public FAXCOMEXLib.FaxServer faxSrv
            { return _faxServer; }
            { _faxServer = value; }

Open in new window

Then I used code like this, to access:
       NightlyInvoiceCreditFaxWorkerProgram nws = new NightlyInvoiceCreditFaxWorkerProgram();
                nws.faxSrv = new FaxServerClass(); 


Open in new window

Because I wrote this into a Windows service, I wrote many events to the Windows event log to see where I was hanging up.  This is a big part of the programming, so you know what's going on.

Then I used this code to listen for events:

                nws.faxSrv.OnOutgoingJobAdded += new FAXCOMEXLib.IFaxServerNotify_OnOutgoingJobAddedEventHandler(faxSrv_OnOutgoingJobAdded);
                nws.faxSrv.OnOutgoingJobChanged += new FAXCOMEXLib.IFaxServerNotify_OnOutgoingJobChangedEventHandler(faxSrv_OnOutgoingJobChanged);
                nws.faxSrv.OnOutgoingJobRemoved += new FAXCOMEXLib.IFaxServerNotify_OnOutgoingJobRemovedEventHandler(faxSrv_OnOutgoingJobRemoved); 

Open in new window

I used the code below for each item I needed to fax, since I send many items at once as a part of a nightly faxing routine:

        try {
         FaxDocument faxDoc = new FaxDocumentClass();
         faxDoc.Priority = FAX_PRIORITY_TYPE_ENUM.fptHIGH;
         faxDoc.ReceiptType = FAX_RECEIPT_TYPE_ENUM.frtNONE; 

            FileStream fs = null;
                fs = File.OpenRead(attachmentPath); 
            catch (IOException)
                InvoiceCreditFaxServiceExVersion.WriteEventToWindowsLog("InvoiceCreditFaxAndEmailServiceExVersion", "Waiting for file to clear", EventLogEntryType.Information, 3);
                goto ReadFile;
                InvoiceCreditFaxServiceExVersion.WriteEventToWindowsLog("InvoiceCreditFaxAndEmailServiceExVersion", "File finally clear", EventLogEntryType.Information, 3);
                if (fs != null)
                    fs = null;
            faxDoc.Body = attachmentPath;
            faxDoc.Subject = thisItem.InvoiceNumber; 
            faxDoc.DocumentName = thisItem.RecipientName + " - Invoice: " + thisItem.InvoiceNumber; 
            faxDoc.Recipients.Add(thisItem.FaxNumber, thisItem.RecipientName); 
            object garb = faxDoc.Submit(faxSrv.ServerName); 
            InvoiceCreditFaxServiceExVersion.WriteEventToWindowsLog("InvoiceCreditFaxAndEmailServiceExVersion", "Successful Fax Send!!", EventLogEntryType.Information, 10); 
            returnString = "Send Success for Item ID: " + thisItem.ID.ToString() + " for: " + thisItem.RecipientName + "  " + thisItem.InvoiceNumber + " "; 
            faxDoc = null;
        }catch (System.Runtime.InteropServices.COMException ce)
                InvoiceCreditFaxServiceExVersion.WriteEventToWindowsLog("InvoiceCreditFaxAndEmailServiceExVersion", "Error connecting to fax server.  Error Message: " + ce.Message + " " + ce.StackTrace, EventLogEntryType.Information, 5);

Open in new window

And, finally the event handlers for the fax server:

        private static void faxSrv_OnOutgoingJobRemoved(FAXCOMEXLib.FaxServer pFaxServer, string bstrJobId)
            InvoiceCreditFaxServiceExVersion.WriteEventToWindowsLog("InvoiceCreditFaxAndEmailServiceExVersion", "Job Removed to outbound queue.", EventLogEntryType.Information, 4);
        private static void faxSrv_OnOutgoingJobChanged(FAXCOMEXLib.FaxServer pFaxServer, string bstrJobId, FAXCOMEXLib.FaxJobStatus pJobStatus)
            InvoiceCreditFaxServiceExVersion.WriteEventToWindowsLog("InvoiceCreditFaxAndEmailServiceExVersion", "There was a fax changed to the outgoing queue.  WAITING UNTIL FINISHED SENDING", EventLogEntryType.Information, 4); 
            while (pJobStatus.Status != FAXCOMEXLib.FAX_JOB_STATUS_ENUM.fjsCOMPLETED)
                //loop until this job is completed, then go back to the program
        private static void faxSrv_OnOutgoingJobAdded(FAXCOMEXLib.FaxServer pFaxServer, string bstrJobId)
            InvoiceCreditFaxServiceExVersion.WriteEventToWindowsLog("InvoiceCreditFaxAndEmailServiceExVersion", "There was a fax added to the outgoing queue.", EventLogEntryType.Information, 4);

Open in new window

The class I used was:

using FAXCOMEXLib;

Open in new window

This seems to work perfectly--it queues up the items into the Windows Fax Viewer, which then takes care of all the rest of the stuff.  If you have any specific questions about this process feel free to let me know.  I'm glad I was able to figure it out (finally), as the documentation online is terrible for this type of thing.

Compatibility is only verified in Windows XP--I didn't try with Vista or 7.
LVL 54

Expert Comment

by:Mark Wills
Thanks, good handy article, will keep this around...

Author Comment

By the way - I programmed this into a Windows Service so that it would "always run" and just set a timer for every 10 minutes to check and see if there is anything new to fax out.  The service itself checks a database table that is updated when a user wants to send a fax out.  If there is anything in status 0, my program sends the items using the code above and then sets the status on them to "1" in the database table.  

As far as I know, this code would work in a Windows Application as well.  In a Windows Application, errors and stuff would be much more visible as well, with no need to write events out to the Windows Log.  If anyone needs any more specific information on this, feel free to contact me via EE.

Featured Post

Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

Join & Write a Comment

Suggested Articles

In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Did you know PowerShell can save you time with SaaS platforms? Simply leverage RESTfulAPIs to build your own PowerShell modules. These will kill repetitive tickets and tabs, using the command Invoke-RestMethod. Tune into this webinar to learn how…
Other articles by this author

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month