Click here to Skip to main content
Click here to Skip to main content

Effortless ActiveX Twain Scanning with Atalasoft’s DotTwain SDK

In general, .NET ActiveX Wrappers are painful to build and deploy. This is because there are a large number of steps involved in the building of signed .NET ActiveX Web Applications. In order to reduce the complexity of this problem, we’ve created a sample solution which works out of the box.

Editorial Note

This article is in the Product Showcase section for our sponsors at CodeProject. These reviews are intended to provide you with information on products and services that we consider useful and of value to developers.

Introduction

In general, .NET ActiveX Wrappers are painful to build and deploy. This is because there are a large number of steps involved in the building of signed .NET ActiveX Web Applications:

  1. Define a set of ActiveX Interfaces to your Control
  2. Define appropriate attributes for each accessible object and interface
  3. Define unique Guids for each accessible object and interface
  4. Mark your control as “Safe for Scripting”
  5. Configure your control to be Self-Registering
  6. Build an installer to register your control and add your references
  7. Build a CAB file which contains your installer and an INF file which executes it
  8. Generate Public/Private Keys in the appropriate format for your signing utility
  9. Configure Signing for Control Assembly and CAB files
  10. Place your Object in said Web Application
  11. Wire up Javascript and Events Correctly

As you can see, this process can be both difficult and time consuming. Additionally, in each of these cases there are a number of pitfalls which can take days to resolve. Indeed, the creation of ActiveX controls has been the bane of many a .NET programmer’s existence.

In order to reduce the complexity of this problem, we’ve created a sample solution which works out of the box. It contains a reference implementation of a UserControl which interacts with Javascript via both method calls and events. Additionally, it takes care of the entire installer and cab file building process for you. Simply download the control, hit F5 and, if Internet Explorer is your default browser, it will run without issue.

http://www.atalasoft.com/download/articles/Initial-ActiveX-Deploy.zip

http://www.atalasoft.com/download/articles/Twain-ActiveX-Deploy.zip

Building a Twain Scanner ActiveX Control

Even without the ActiveX component of the project, TWAIN is quite a complex API on its own. Thankfully, our .NET Scanning SDK makes it as simple as dropping a control on a page. To this end, head on over to our site and download a free evaluation copy of DotTwain. Once you have it installed and registered we can begin building our ActiveX Control by opening the Initial ActiveX Deploy solution.

Step 1 – Add the Acquisition Object

The first simple step is to drag the Acquisition onto the ExampleControl’s design view.

image001.gif

This will add an Acquisition Class object definition named acquisition1 to our ExampleControl class and, in addition, add all necessary references to our project. The Acquisition class takes care of everything you need for simple to moderately complex scanning solutions in .NET WinForms. Now it’s just a matter of a little wiring to make it scan.

Step 2 – Initialization of the Acquisition Object

For error handling and messaging we can use the SomethingHappenedEvent via our provided d method.

public ExampleControl()
{
    InitializeComponent();
    acquisition1.AcquireCanceled += new EventHandler(acquisition1_AcquireCanceled);
    acquisition1.ImageAcquired += new Atalasoft.Twain.ImageAcquiredEventHandler(
        acquisition1_ImageAcquired);
}

void acquisition1_ImageAcquired(object sender, Atalasoft.Twain.AcquireEventArgs e)
{
    SetLabelText("Image Acquired”);
}

void acquisition1_AcquireCanceled(object sender, EventArgs e)
{
    SetLabelText("Acquire Canceled");
}

When SetLabelText is called, the SomethingHappenedEvent will be invoked with the specified string.

Step 3 – Add Scanning Code to the Control

For the sake of simplicity, we’re going to use the already existing InternalClickButton() method for our scan button and use the default scanner.

private void Scan()
{
    if (!acquisition1.SystemHasTwain || acquisition1.Devices.Count < 0)
    {
        SetLabelText("No Twain devices found on the System");
    }

    else if (!acquisition1.Devices.Default.CanOpen())
    {
        SetLabelText("Cannot open default device");
    }
    else
    {
        // ModalAcquire is required by IE.
        acquisition1.Devices.Default.ModalAcquire = true;
        acquisition1.Devices.Default.Acquire();
    }
}

private void InternalClickButton(string textlabel)
{
    SetLabelText(textlabel);
    Scan();
}

By pasting these two code snippets in and overwriting the existing ExampleControl() and InternalClickButton() methods, you now have a working ActiveX Twain Solution.

Deployment

While the previous result will work locally, some steps still need to be taken before deployment. This is due to two factors outside of our control: Guids must be unique to the control/interface and keys must be unique to the user.

The following three steps are necessary to ensure that both your Guids are unique and your files are securely signed.

  1. Set Unique Guids.
  2. Set the Guid in the Default.aspx file’s object tag must match the control.
  3. Generate new keys and configure signing your Assembly and Cab file.

Thankfully, these are both relatively easy tasks to accomplish.

Step 1 – Setting Unique Guids

The ExampleControl class and each of its declared interfaces must have unique Guids. This is because the Guid is what windows uses to identify these constructs under the hood. To accomplish this task we must replace each existing Guid with a fresh one made with Visual Studio’s Guid generator.

In my example we have three Guids: One for IExposedComMembers, one for IExposedComEvents and one for the ExampleControl itself. Each of these three Guids must be replaced.

Note that there is an additional Guid tag in the ExampleControl.ActiveX.cs file. Do not replace this Guid! It specifies the IObjectSafety interface to be imported. In fact, without further research on the exact repercussions, I suggest not changing anything in the ExampleControl.ActiveX.cs file as it will work perfectly well if left as-is in the vast majority of cases.

[Guid("B7C65243-6002-45fe-B9B0-27316F289646")]
public interface IExposedComMembers
{
…
}

[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("0F05ECBA-A254-4bd3-973F-C6145A3D2082")]
public interface IExposedComEvents
{
…
}

[ProgId("ExampleControl")]
[ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(IExposedComEvents))]
[ComVisible(true)]
[Guid("56113B3E-0616-4e68-BABC-7CAE3352DF68")]
public partial class ExampleControl : UserControl
{
…
}

The Guid generator can be found under Visual Studio’s Tools menu under the title Create Guid.

image002.jpg

To use the Guid Generator, first ensure that “4. Registry Format” is selected. Then, for each Guid to be replaced, click “New Guid” and then “Copy”. You can then simply highlight the text portion of the attribute. The result will look like this.

[Guid("{C025FB74-9813-4dcf-B2EE-9AF475769E93}")]

You must then delete the braces { } from both sides of each pasted Guid:

[Guid("C025FB74-9813-4dcf-B2EE-9AF475769E93")]

Step 2 – Setting the correct Guid for your control

After changing your control’s Guid the Default.aspx must be changed to match it. The definition inside the Default.aspx like the following:

<object id="ActiveXExample" name="ActiveXExample"
    classid="clsid:56113B3E-0616-4e68-BABC-7CAE3352DF68"
    codebase="ActiveX.cab#version=1,0,0,0" VIEWASTEXT></object>

All that is needed here is for the text following clsid: to match the Guid you generated for your control. So if, for example, your control now looks like:

[ProgId("ExampleControl")]
[ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(IExposedComEvents))]
[ComVisible(true)]
[Guid("C025FB74-9813-4dcf-B2EE-9AF475769E93")]
public partial class ExampleControl : UserControl
{
…
}

Your object tag should appear as follows:

<object id="ActiveXExample" name="ActiveXExample"
    classid="clsid:C025FB74-9813-4dcf-B2EE-9AF475769E93"
    codebase="ActiveX.cab#version=1,0,0,0" VIEWASTEXT></object>

Step 3 – Signing you Application

To ease initial development I’ve included a pre-generated key with my solution. However, deploying your application with the included key is a terrible idea. This is because if anyone else were to find this example and my pre-generated key set, they would be able to spoof your control and compromise your client’s machines.

The first step is to generate your own set of cer, pfx, pvka and spc key files. This is not a trivial task. However, a very well written walkthrough on how to do this can be found here.

Once you have these files generated only three things remain to be done.

  1. Take these resulting files and place them in the \ActiveXExample\Tools directory of your solution.
  2. Put the name of your .pfx file in filename.txt and your signing password in password.txt.
  3. In Visual Studio, go to the signing tab in the properties of your ActiveXExample project and change the strong name key file to your newly generated .snk.

Once you have completed this, rebuild your solution. At this point you will have a working ActiveX Twain Solution which is ready for deployment.

Going Further

With this, we’ve hidden most of the complexity in ActiveX deployment. However, for a reasonably sized application it will likely be necessary to learn about the details of this implementation. For additional information, I suggest reading the following excellent articles:

Michal Kosmala’s Create ActiveX in .NET Step by Step
Anand Todkar’s Downloading C# ActiveX Components through CAB File
Sharon Salmon’s Handling HTML Events from .NET, using C#
HOWTO: Deploy DotTwain from Internet Explorer

Conclusion

With this article, I hope we’ve been able to reduce your Twain ActiveX deployment from a month long ordeal to a day-long project. Should you run into any bumps in the road along the way, our fantastic support team is available to help you through any problem you might have. Also, if you find yourself in need of an ActiveX document imaging solution, our .NET Imaging SDK is similar to our Twain toolkit in terms of ease of use and deployment.

Archives

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Richard Minerich
Software Developer Atalasoft, Inc.
United States United States
At Atalasoft I work with OCR, Raw Image Formats, Exif Data and Pdf Documents. My interests include Machine Learning, Concurrency and Computer Languages.

Comments and Discussions

 
QuestionLinks not working PinmemberMember 827668217-Oct-11 21:45 
AnswerRe: Links not working PinmemberRichard Minerich18-Oct-11 4:08 
GeneralRe: Links not working Pinmembervincennes16-Jan-12 21:51 
NewsAdditional Links PinmemberRichard Minerich14-Jul-09 6:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140709.1 | Last Updated 12 Jun 2009
Article Copyright 2009 by Richard Minerich
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid