Abstract

In Windows imaging applications, the most used API for scanning is TWAIN www.twain.org.
Unfortunately, the new .NET Framework has no built-in support for TWAIN. So we have to work with the interop methods of .NET to
access this API. This article doesn't explain this interop techniques, and good knowledge of the
TWAIN 1.9 specifications is assumed! The sample code included doesn't present a
finished library, only some essential steps for a minimal TWAIN adaption to .NET applications.

Details

First step was to port the most important parts of TWAIN.H, these are found in TwainDefs.cs. The real logic for
calling TWAIN is coded in the class Twain, in file TwainLib.cs.. As the TWAIN API is exposed by the Windows
DLL, twain_32.dll, we have to use the .NET DllImport mechanism for interop with legacy code. This DLL has the
central DSM_Entry(), ordinal #1 function exported as the entry point to TWAIN. This call has numerous parameters,
and the last one is of variable type! It was found to be best if we declare multiple variants of the call like:

For some sort of 'callbacks', TWAIN uses special Windows messages, and these must be caught from the application-message-loop.
In .NET, the only way found was IMessageFilter.PreFilterMessage(), and this filter has to be activated with a call
like Application.AddMessageFilter(). Within the filter method, we have to forward each message to
Twain.PassMessage(), and we get a hint (enum TwainCommand) back for how we have to react.

Sample App

The sample is a Windows Forms MDI-style application. It has the two TWAIN-related menu items Select Source... and
Acquire... Once an image is scanned in, we can save it to a file in any of the GDI+ supported file formats (BMP, GIF,
TIFF, JPEG...)

Limitations

All code was only tested on Windows 2000SP2, with an Epson Perfection USB scanner and an Olympus digital photo camera. The
scanned picture is (by TWAIN spec) a Windows DIB, and the sample code has VERY little checking against error return codes and
bitmap formats. Unfortunately, no direct method is available in .NET to convert a DIB to the managed Bitmap class... Some known
problems may show up with color palettes and menus.

Hi NETMaster.
I downloaded your source and also your demo.
The demo works perfect, nice, like a charm. But when I open the source in visual studio 2013 and run the project, it gives me the "BadImageFormatException was unhandled" exception. Here's the details of the exception :

An unhandled exception of type 'System.BadImageFormatException' occurred in TwainGui.exe
Additional information: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

please tell me where the problem is.
Thanks very much in advance,
Mahdi Tahsildari

Hi
I have the same problem, My pc is running at 64-bit. I think this is about if your pc is using 32 or 64 bit driver for your scanner. To test, download twack_32 and twack_64, and see which of the two apps will run your scanner.

Now with regards to the exception: Go to Project properties > under Build tab > under Platform target, check Prefer 32-bit.

First, thank you for the great works!
I ran into an issue. The application crashed when I quit after scanning. It shows "vshost32.exe has stopped working". Here are my settings: Windows 7 x64, Visual Studio 2013, target x86 and .net framework 4.5. Please help me if you know the answer!

In my requirement, I should display only twain drivers supported scanners. But when I call Select Source, it is showing all the list of scanners, cameras in it. Can I get only twain ones alone by setting any property?

2) How to perform automatic scanning of image when placing an ID card in the ID scanner device?

3) How to perform Scanning operation for the Front and Back side of ID card?

4) How to perform Scanning of UV( Ultraviolet) and IR(Infrared) type ID Cards?

5) After scanning the images how to edit feature's like Calibrate, Resolution, Height, Width, Color, Image Brightness, Image Contrast, Invert Images? If so by which method and parameters can be applied?

Hi I saw that this question was not answered so maybe I can help.
you should set XferCount = -1 to scan all papers in scanner else for single page set XferCount = 1 .
So in TwainLib.cs:
TwCapability cap = new TwCapability( TwCap.XferCount, -1 );
instead of
TwCapability cap = new TwCapability( TwCap.XferCount, 1 );

WE HAVE A DLL TO SCAN AN IMAGE AND GET DATA FROM FILE SCANNED SEPARATING PARTS AND STORING DATA OBTAINED IN DATABASE.
THE QUESTION IS, WHERE THE TWAIN STANDARD SAVE THE TEMP FILE OF THE IMAGE OBTAINED.
I NEED TO MAKE A MODIFICATION TO PUT THE FILE IN A ROOT WITHOUT SCAN IMAGE
SO SORRY FOR MY ENGLISH.
PLEASE, HELP ME.