Programmatically Controlling Windows Fax Services Using VB.net
Windows fax services began to be available in Windows 2003 Server. The service was an advance over the alternatives of the time. As you probably guessed from the title, it can be controlled with a Visual Basic.NET application, which we will begin writing in this article.
Contributed by Luke Niland Rating: / 17 July 16, 2007
Prior to Windows 2003 Server, if you wanted a software-based faxing solution, you had to purchase a commercial offering (such as Genifax) or use an open source product such as Hylfax.
The problems with using these other products is the obvious one of cost, and with the open source products there is always the problem of getting support. As most of them run on the Linux platform the support staff need some knowledge of Unix for troubleshooting and set up purposes.
Then, when Windows 2003 Server was released it came with its own built-in fax services. It has all the features of the commercial products, such as being able to support multiple modems, send email confirmation when the job is sent, receive faxes and route to a mailbox/printer/Folder based on the number it came in on and many more. The difference is that these features are built directly into the operating system.
Another advantage it has is that we can programmatically control it using the FAXCOMEX.dll library. In this article we are going to write an application in Visual Basic.NET that will control the fax service.
Installing the Fax Service on the Server
Before installing the fax services on the machine, it's a good idea to install all the modems you are going to use, so the setup will be able to use them when the service installs. I'm not sure of the maximum number of modems it will support; I think it's six but this might not be accurate.
The first step is installing and setting up the fax service on the server (remember it must be running 2003). This is done in the normal way; go into the control panel, Add/Remove programs, Add/Remove Windows components, then click on the Fax Services option and it will be installed onto your server.
If the set up runs through without any problems, you should have a new folder in the start menu under communications, and if you answered yes during set up to create a shared fax device, you will be able to connect to the server from client machines to send a fax.
Before you go any further, send out a test fax using the Send Fax Wizard in the start menu. This will confirm that it is going to work and there's not any problems with the modems or elsewhere in the system. Send it to a local fax machine so you can see the output.
If your test page came through okay, we can now look at some of the settings of the fax service. Most of these can be controlled via your application but it doesn't hurt to know where they are.
Fire up the Fax Services Manager application. This is where most of the configuration is carried out.
As you can see from the screen shot, you can see all the modems that the service is going to use, as well as the incoming and outgoing routing rules and the cover pages available on the server.
Most of the useful options can be set by right clicking on the Fax (local) icon at the top, then clicking on Properties.
There are quite a few options in here. For now just go into the Receipts tab. In this tab we can tell the fax service where the SMTP server is located, and under what email address to send out the fax.
This is used to email information to an address. The email is sent when a job has been processed on the server, and contains things like the job status (sent, failed, canceled, etc.), how long it took to send, how many retries were made and other useful stats.
It's very unlikely you will be writing the application on the same machine on which you have installed the fax services, so you need to connect to the shared fax device on your development machine. Its just as simple as running the Add Printer wizard and pointing it at the shared fax device on the server.
Once you have installed it on your machine, send another test fax from your machine, and also make it email you a job receipt (on the delivery notification screen, give it your email address). If the job is successful the fax should arrive on your fax machine, and you should receive an email in your in box that looks similar to this:
Fax Fax Job #!72686!# was successfully sent to Customer at 01772 123456
Fax submitted: 17:05:04
To server: fax1-svr
Transmission started: 17:05:05
Transmission end: 17:06:27
Number of retries: 1
Number of pages: 2
You can also look at the job information on the fax server by using the fax console app. This lists all incoming and outgoing jobs in a similar way to Outlook, and shows all the information and documents associated with the job.
If that has worked okay, you now need to get a copy of the fxscomex.dll file. This is contained in the Windows 2003 Platform SDK. You need to install the Core platform SDK. It can be downloaded from http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
When you have installed this, look in your Windows folder for a file called fxscomex.dll, and just to be on the safe side, run regsvr32 on this file to make sure it's registered. Once that is done, fire up Visual Studio and create a new Visual Basic project called something like TestFaxServices.
Once the project has been created, add a COM reference to the dll. To do this in Visual Studio go into the Project menu, then Add Reference and click on the COM tab. From the list, select Microsoft Fax Service Extended COM Type Library and hit the select button, then OK. You are now set up to use the library.
As a test the first thing we will do is make sure we can connect to the fax server. This is very simple and can be achieved with just a few lines of code. Put a button on your form, and in the click event of the button type the following code. Each part is discussed underneath:
Dim objFaxServer As New FAXCOMEXLib.FaxServer
Dim objFaxOutgoingQueue As FAXCOMEXLib.FaxOutgoingQueue
The first two lines of code are variables that hold the connections to the server, and the outgoing queue properties. Both types live in the FAXCOMEXLib, as does everything else we use when talking to and configuring the server.
We enclose the whole block of code in a Try Catch block, so we can handle any exceptions gracefully. The first line within the Try is connecting to the fax server, using the objFaxServer variable's Connect method. You just need to give it the name or the IP address of the server. Here it is hard coded but in the real world you would probably put the server name in a config file, or look it up directly.
Once we have a connection, we can start to set the outgoing queue options. The next section of code sets our objFaxOutgoingQueue variable to be the current Outgoing queue of the server (basically, the variable now contains the current settings on the outgoing queue). Then we make sure the outgoing queue is ready to send out jobs by telling it not to be blocked, or paused. Then, we set the number of retries for the job (in this case three) and how long in minutes to wait before each retry (in this case one).
We then call the Save method of the queue variable to write out new settings down to the server. If you don't call the Save method, none of the setting we have specified will change so it's very important to remember to do this. The rest of the code just pops up a message box, and closes the Try/Catch.
If all has gone well, at this point when you run the code you should be given a message box telling you the new settings have been saved. However, if an error has occurred somewhere you will get a message saying 'Fax Error' along with a description of the error.
As this code is not doing much apart from really testing connectivity between you and the service, the error is probably going to be something involving the name of the server being wrong (in the objFaxServer.Connect("srv-fax1") line), or possibly a security issue. The error message normally gives you a good indication of what has happened.
If all has gone well, you are now ready to start sending jobs to the server and getting its current load and jobs. This is covered in part two of the article, so stay tuned!