<

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x

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

Published on
19,942 Points
10,242 Views
2 Endorsements
Last Modified:
Awarded
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
        {
            get
            { return _faxServer; }
            set
            { _faxServer = value; }
        } 
       

Open in new window


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

                nws.faxSrv.Connect(""); 
        

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.ListenToServerEvents(FAXCOMEXLib.FAX_SERVER_EVENTS_TYPE_ENUM.fsetOUT_QUEUE); 
                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; 

        //THIS CODE IS TO MAKE SURE THE FILE IS NOT IN USE WHEN WE TRY TO ATTACH AND THEN SEND
        ReadFile:
            FileStream fs = null;
            try
            {
                fs = File.OpenRead(attachmentPath); 
            }
            catch (IOException)
            {
                InvoiceCreditFaxServiceExVersion.WriteEventToWindowsLog("InvoiceCreditFaxAndEmailServiceExVersion", "Waiting for file to clear", EventLogEntryType.Information, 3);
                goto ReadFile;
            }
            finally
            {
                InvoiceCreditFaxServiceExVersion.WriteEventToWindowsLog("InvoiceCreditFaxAndEmailServiceExVersion", "File finally clear", EventLogEntryType.Information, 3);
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                    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.
2
Author:MrJesse34
2 Comments
LVL 56

Expert Comment

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

Author Comment

by:MrJesse34
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.
0

Featured Post

Rowby Goren Makes an Impact on Screen and Online

Learn about longtime user Rowby Goren and his great contributions to the site. We explore his method for posing questions that are likely to yield a solution, and take a look at how his career transformed from a Hollywood writer to a website entrepreneur.

Suggested Articles

Key to your CPU's ability to stay cool is to use the right amount of thermal paste and apply it correctly. In other words you want as much thermal conductivity between CPU and the cooling block. Use a quality thermal paste and apply it in a manner…
Discover the basics of using Outlook 2016 from office 365.
Other articles by this author

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month