<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>interop</title>
        <link>http://geekswithblogs.net/btudor/category/9462.aspx</link>
        <description>interop</description>
        <language>en-US</language>
        <copyright>Bill Tudor</copyright>
        <managingEditor>btudor@nycap.rr.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Golden Rules for Installing new Hardware</title>
            <link>http://geekswithblogs.net/btudor/archive/2009/01/27/128997.aspx</link>
            <description>&lt;p&gt;When installing new hardware, always observe the Three Golden Rules:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Never insert the manufactures CD/DVD into the computer &lt;/li&gt;
    &lt;li&gt;If the hardware was made by HP, see Rule #1. &lt;/li&gt;
    &lt;li&gt;If there is a bright green, pink, or yellow sheet of paper in the box that says something like “STOP – insert CD and run setup before connecting your equipment”, see Rule #1. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You will never want to run the manufactures installation CD. If &lt;em&gt;&lt;strong&gt;you&lt;/strong&gt;&lt;/em&gt; cannot get the hardware to work with the operating system, &lt;em&gt;you might as well bring it back to the store&lt;/em&gt;. So, shutdown the computer, install the hardware device, start back up. Did Windows recognize the device? Did Windows supply a generic driver or a driver from the manufacturer? Is there a newer driver available from the manufacturer? &lt;/p&gt;
&lt;p&gt;Use the Device Manager and the manufacturers web site to answer these questions. Update the driver. No crap-ware. &lt;/p&gt;
&lt;p&gt;  &lt;/p&gt;
&lt;h4&gt;But I want that ink-monitoring program in my system tray&lt;/h4&gt;
&lt;p&gt;Recently, I purchased and installed a new scanner – a Canon Cano Scan LiDE90. Following the golden rules worked like a charm except that the four little buttons on the front of the scanner - Copy - Photo - PDF - E-Mail are non-functional. A little poking around the registry and I found the entries tied to those buttons. Now, all I have to do is write a program. &lt;/p&gt;
&lt;h3&gt;Windows Image Acquisition&lt;/h3&gt;
&lt;p&gt;I decided to use WIA (v2) via COM interop in a WPF application. It seems there are some choices when reading data from a scanner, and I am not at all sure if I made the right one, but for my simple requirements it will have to do.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Scan a full-page image using default settings &lt;/li&gt;
    &lt;li&gt;Print the image as a single page to the default printer &lt;/li&gt;
    &lt;li&gt;Exit &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The application will run in this manner when executed with a command line option instructing this &lt;em&gt;scan-print-quit&lt;/em&gt; behavior with nothing but a progress bar for a UI. When executed normally, however, the UI allows you to:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Choose a scanner &lt;/li&gt;
    &lt;li&gt;Choose a printer &lt;/li&gt;
    &lt;li&gt;Adjust brightness and contrast &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is where WPF comes in. Let’s see how good of a dev-signer I am (not!). The settings chosen are saved as default for the next Copy button press quick-scan-print operation. The first time the application runs, of course, it will have to show the UI to get the initial settings. The user can also run whenever they want to use their new “photo copy machine”, as well as press the Copy button on the scanner for a quick copy.&lt;/p&gt;
&lt;h4&gt;Choosing a scanner&lt;/h4&gt;
&lt;p&gt;I admit that I did not spend time studying the WIA API documentation. It seems that most of the action seems to be done with the CommonDialogClass COM object wrapper class.&lt;/p&gt;
&lt;p&gt; &lt;font face="Courier New" size="2"&gt;1: CommonDialogClass wiaDiag = new CommonDialogCl&lt;span&gt;ass(&lt;/span&gt;); &lt;br /&gt;
2: Device d = wiaDiag.ShowSelectDevice(WiaDeviceType.ScannerDeviceType, true, false); &lt;br /&gt;
3: if (d != null) &lt;br /&gt;
4: { &lt;br /&gt;
5:     _deviceID = d.DeviceID; &lt;br /&gt;
6:     // Find the device name &lt;br /&gt;
7:     foreach (IProperty p in d.Properties) &lt;br /&gt;
8:     { &lt;br /&gt;
9:         if (p.Name == "Name") &lt;br /&gt;
10:         { &lt;br /&gt;
11:             result = p.get_Value(&lt;span&gt;)&lt;/span&gt;.ToString&lt;span&gt;(&lt;/span&gt;); &lt;br /&gt;
12:             break; &lt;br /&gt;
13:         } &lt;br /&gt;
14:         Marshal.FinalReleaseComObject(p); &lt;br /&gt;
15:     } &lt;br /&gt;
16:     Marshal.FinalReleaseComObject(d); &lt;br /&gt;
17: } &lt;br /&gt;
18: Marshal.FinalReleaseComObject(wiaDiag); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;In the code snippet above, I am letting the user choose a scanner and then storing the name. When performing the scan, I will search through the scanner devices for the chosen name, and extract that device with the matching name to determine which one to use. The name is stored to user settings on disk. There are a couple of things about this code that are worth noting:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;The code must be wrapped in T&lt;span&gt;RY CA&lt;/span&gt;TCH since a ComException is thrown even in expected cases, such as when there are no scanners connected to the computer. &lt;/li&gt;
    &lt;li&gt;I am not at all sure if the FinalReleaseComObject(&lt;span&gt;)&lt;/span&gt; methods need to be called like that. Particularly for the iteration of the property objects. I do very little COM interop. &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Grabbing the Image with Minimal UI&lt;/h4&gt;
&lt;p&gt;To grab the image with minimal UI (just a progress bar), you can connect to the device, grab the first item (dealing with the COM goo by actually grabbing the second array element of the Items collection), and creating a new WPF BitmapImage to return as the result.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
1: BitmapImage result = null; &lt;br /&gt;
2: DeviceManager manager = new DeviceManagerClass(&lt;span&gt;)&lt;/span&gt;; &lt;br /&gt;
3: Device d = null; &lt;br /&gt;
4: foreach (DeviceInfo info in manager.DeviceInfos) &lt;br /&gt;
5: {&lt;/p&gt;
&lt;pre&gt; &lt;/pre&gt;
&lt;br /&gt;
6: if (info.DeviceID == _deviceID) &lt;br /&gt;
7: { &lt;br /&gt;
8: d = info.Co&lt;span&gt;nnect()&lt;/span&gt;; &lt;br /&gt;
9: break; &lt;br /&gt;
10: } &lt;br /&gt;
11: } &lt;br /&gt;
12: if (d != null) &lt;br /&gt;
13: { &lt;br /&gt;
14: Item item = d.Items[1]; &lt;br /&gt;
15: CommonDialogClass wiaDiag = new CommonDialogClass(); &lt;br /&gt;
16: ImageFile file = (ImageFile)wiaDiag.ShowTransfer(item, wiaFormatJPEG, false); &lt;br /&gt;
17: WIA.Vector vector = file.FileData; &lt;br /&gt;
18:  &lt;br /&gt;
19: result = new BitmapImage(); &lt;br /&gt;
20: result.BeginInit(); &lt;br /&gt;
21: result.StreamSource = new MemoryStream((byte[])vector.get_BinaryData()); &lt;br /&gt;
22: result.EndInit(); &lt;br /&gt;
23: } &lt;br /&gt;
24: 
&lt;p&gt;One snag: I needed to set the “Horizontal Extent”, “Vertical Extent”, “Horizontal Resolution”, and “Vertical Resolution” properties on the item before calling ShowTransfer(&lt;span&gt;)&lt;/span&gt;, otherwise only a partial page was returned for my device.&lt;/p&gt;
&lt;p&gt;In the end, I was able to follow the “Three Golden Rules” and still get my copy button to work.&lt;/p&gt; &lt;img src="http://geekswithblogs.net/btudor/aggbug/128997.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Bill Tudor</dc:creator>
            <guid>http://geekswithblogs.net/btudor/archive/2009/01/27/128997.aspx</guid>
            <pubDate>Tue, 27 Jan 2009 06:09:06 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/btudor/comments/128997.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/btudor/archive/2009/01/27/128997.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/btudor/comments/commentRss/128997.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/btudor/services/trackbacks/128997.aspx</trackback:ping>
        </item>
    </channel>
</rss>
