Getting the WIA scripting automation to remember scanner settings in C#
This is a bit of a hack, but maybe it will help someone in the future when they discover that the Windows XP Scanner and Camera wizard doesn't remember the previous settings in subsequent scans. Very frustrating.
Get the Windows Image Acquisition Automation Library v2.0 and install wiaaut.dll and download the WindowFinder class from http://www.thecodeproject.com/csharp/InteropSignon.asp to simplify working with the dialogs and sending window messages to the controls on the dialog.
Add the "Microsoft Windows Image Acquisition Library v2.0" COM reference to your project.
The simplest code to select a scanner and connect to it is as follows, where WIACommonDialog is an instance of the CommonDialogClass.
Device d = this.WIACommonDialog.ShowSelectDevice(WiaDeviceType.ScannerDeviceType,true,false);
We need the name of the device to capture the window handle later
string deviceName = "";
foreach (Property property in d.Properties)
{
if (property.Name == "Name")
{
deviceName = ((IProperty)property).get_Value().ToString();
}
}
To get items from the scanner we use the following code
Items items = WIACommonDialog.ShowSelectItems(d);
foreach (Item item in items)
{
ImageFile imageFile = (ImageFile)WIACommonDialog.ShowTransfer(item);
Vector vector = imageFile.FileData;
byte[] bin = (byte[])vector.get_BinaryData();
//do something with the image data
}
Which will show a dialog like this

If we change the radio button to Custom Settings then it remembers the settings, but by default it always goes back to Color picture. Just before ShowSelectItems we start a new thread using this function and assign _dialogTitle = "Scan using " + deviceName;
public void WaitForWindow()
{
try
{
WindowFinder scanWindowFinder = new WindowFinder();
IntPtr wizardHandle = IntPtr.Zero;
while (wizardHandle == IntPtr.Zero)
{
Thread.Sleep(50);
wizardHandle = scanWindowFinder.Find("#32770",_dialogTitle);
}
scanWindowFinder.UseWindow(wizardHandle);
WindowFinder customButton = new WindowFinder();
IntPtr buttonPtr = IntPtr.Zero;
buttonPtr = customButton.Find(wizardHandle,"Button","&Custom Settings");
customButton.UseWindow(buttonPtr);
customButton.ClickButton();
}
catch (ThreadAbortException)
{
//swallow the exception
}
}
The values are obtained using SPY++
