WIA - Problem with Com

D

David

Hi all,

I am having problems with the WIA Com object and I am not sure what I am
doing with it...



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WIA;
using System.Runtime.InteropServices;
using System.Configuration;

namespace Scan
{
public partial class Test : Form
{
private const int WIA_DPS_DOCUMENT_HANDLING_SELECT_FEEDER = 1;
private const int WIA_DPS_DOCUMENT_HANDLING_SELECT_FLATBED = 2;

private const int WIA_DPS_DOCUMENT_HANDLING_STATUS_FEED_READY = 1;

private const int WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS = 1024;
private const int WIA_PROPERTIES_WIA_DIP_FIRST = 2;
private const int WIA_PROPERTIES_WIA_DPA_FIRST =
WIA_PROPERTIES_WIA_DIP_FIRST + WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS;
private const int WIA_PROPERTIES_WIA_DPC_FIRST =
WIA_PROPERTIES_WIA_DPA_FIRST + WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS;

private const int WIA_PROPERTIES_WIA_DPS_FIRST =
WIA_PROPERTIES_WIA_DPC_FIRST + WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS;

private Object WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_STATUS =
WIA_PROPERTIES_WIA_DPS_FIRST + 13;
private Object WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_SELECT =
WIA_PROPERTIES_WIA_DPS_FIRST + 14;


WIA.CommonDialog dlg = new WIA.CommonDialogClass();
Device Scanner;


public Test()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
RunScan();
}

private void Test_FormClosed(object sender, FormClosedEventArgs e)
{
if (dlg != null)
Marshal.ReleaseComObject(dlg);
if (Scanner != null)
Marshal.ReleaseComObject(Scanner);
}

private void Test_Load(object sender, EventArgs e)
{

}

private void button2_Click(object sender, EventArgs e)
{
Scanner =
dlg.ShowSelectDevice(WiaDeviceType.UnspecifiedDeviceType, true, false);
}

private void RunScan()
{
int ScanCount = 0;
bool ReadyForScan = IsPaperInFeeder();
ImageFile[] img = null; // = new ImageFile[]();

while (ReadyForScan)
{

WIA.Item scanItem = Scanner.Items[1];

img[ScanCount] =
(ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatJPEG);
int FrameCount = img[ScanCount].FrameCount;

ReadyForScan = IsPaperInFeeder();

string scanTime = DateTime.Now.ToFileTime().ToString();

string FileName = "c:\\tempimage_" + scanTime + ".jpg";

img[ScanCount].SaveFile(FileName);


Marshal.ReleaseComObject(scanItem);

ScanCount++;
}
Marshal.ReleaseComObject(img);
}

public bool IsPaperInFeeder()
{
if (Scanner == null) throw new Exception("Scanner device must be
selected and connected!");

//get the two properties
Property documentHandlingSelect = null;
Property documentHandlingStatus = null;

//foreach (Property prop in Device.Properties)
foreach (Property prop in Scanner.Properties)
{
if (prop.PropertyID ==
(int)WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_SELECT)
documentHandlingSelect = prop;
if (prop.PropertyID ==
(int)WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_STATUS)
documentHandlingStatus = prop;
}

bool hasMorePages = false; //assume there are no more pages

if (documentHandlingSelect != null) //may not exist on flatbed
scanner but required for feeder
{
//check for document feeder
int feederFlag =
unchecked((int)documentHandlingSelect.get_Value());

if ((feederFlag & WIA_DPS_DOCUMENT_HANDLING_SELECT_FEEDER)
!= 0)
{
int feedReadyFlag =
unchecked((int)documentHandlingStatus.get_Value());
hasMorePages = ((feedReadyFlag &
WIA_DPS_DOCUMENT_HANDLING_STATUS_FEED_READY) != 0);
}
}

return hasMorePages;
}

}
}


I am getting Object reference not set to an instance of an object...

Use the "new" keyword to create an object instance

This is on the line img[ScanCount] =
(ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatJPEG);

I have a breakpoint in on that line. It breaks, I click step into, the
scanner then scans and partially ejects the last document, but then I get a
green break on that line with the above error.

If I try to step again, I get the green break on the same line with "Value
does not fall within the expected range"

Step again, the project stopped, but the scanner is still saying "Scanning"

I have found some VB.NET code and I am trying to convert it to C# and to fit
my application. The above code is my test application so that I can give you
as much working code as I can.

The VB.NET code is at http://www.xtremevbtalk.com/showthread.php?t=288758
(message 8). While mine is slightly different, I have tried to implement
some of what it is suggesting.

Also, I am not sure if I am disposing of the WIA object properly, I have
tried a number of things, which includes the Marshal.ReleaseComObject and
also just setting the object to null. Now, this is an area I am not familiar
at all.

The scanner is a HP Scanjet N6350, network scanner with an ADF. I need to be
able to scan all the documents via the ADF, as mentioned above, the
scanItem.Transfer will trigger the scan, I have 3 docs loaded and it passes
all docs through but partially holds onto the third, whilst still saying
"Scanning" on the scanner panel.



Like always, any help or pointers would be very much appreciated.

--
Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
 
D

David

Hello,

I know that WIA is not everyones speciality. Unfortunately, there is not a
lot of info on the net about using it within .NET and what I do find is not
quite suitable for what I am trying to achieve.

However, my main question here is am I using COM correctly? Am I closing it
down properly so that I can re-use it later?

Any WIA responses would be a bonus.

--
Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available


David said:
Hi all,

I am having problems with the WIA Com object and I am not sure what I am
doing with it...



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WIA;
using System.Runtime.InteropServices;
using System.Configuration;

namespace Scan
{
public partial class Test : Form
{
private const int WIA_DPS_DOCUMENT_HANDLING_SELECT_FEEDER = 1;
private const int WIA_DPS_DOCUMENT_HANDLING_SELECT_FLATBED = 2;

private const int WIA_DPS_DOCUMENT_HANDLING_STATUS_FEED_READY = 1;

private const int WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS = 1024;
private const int WIA_PROPERTIES_WIA_DIP_FIRST = 2;
private const int WIA_PROPERTIES_WIA_DPA_FIRST =
WIA_PROPERTIES_WIA_DIP_FIRST + WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS;
private const int WIA_PROPERTIES_WIA_DPC_FIRST =
WIA_PROPERTIES_WIA_DPA_FIRST + WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS;

private const int WIA_PROPERTIES_WIA_DPS_FIRST =
WIA_PROPERTIES_WIA_DPC_FIRST + WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS;

private Object WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_STATUS =
WIA_PROPERTIES_WIA_DPS_FIRST + 13;
private Object WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_SELECT =
WIA_PROPERTIES_WIA_DPS_FIRST + 14;


WIA.CommonDialog dlg = new WIA.CommonDialogClass();
Device Scanner;


public Test()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
RunScan();
}

private void Test_FormClosed(object sender, FormClosedEventArgs e)
{
if (dlg != null)
Marshal.ReleaseComObject(dlg);
if (Scanner != null)
Marshal.ReleaseComObject(Scanner);
}

private void Test_Load(object sender, EventArgs e)
{

}

private void button2_Click(object sender, EventArgs e)
{
Scanner =
dlg.ShowSelectDevice(WiaDeviceType.UnspecifiedDeviceType, true, false);
}

private void RunScan()
{
int ScanCount = 0;
bool ReadyForScan = IsPaperInFeeder();
ImageFile[] img = null; // = new ImageFile[]();

while (ReadyForScan)
{

WIA.Item scanItem = Scanner.Items[1];

img[ScanCount] =
(ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatJPEG);
int FrameCount = img[ScanCount].FrameCount;

ReadyForScan = IsPaperInFeeder();

string scanTime = DateTime.Now.ToFileTime().ToString();

string FileName = "c:\\tempimage_" + scanTime + ".jpg";

img[ScanCount].SaveFile(FileName);


Marshal.ReleaseComObject(scanItem);

ScanCount++;
}
Marshal.ReleaseComObject(img);
}

public bool IsPaperInFeeder()
{
if (Scanner == null) throw new Exception("Scanner device must
be selected and connected!");

//get the two properties
Property documentHandlingSelect = null;
Property documentHandlingStatus = null;

//foreach (Property prop in Device.Properties)
foreach (Property prop in Scanner.Properties)
{
if (prop.PropertyID ==
(int)WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_SELECT)
documentHandlingSelect = prop;
if (prop.PropertyID ==
(int)WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_STATUS)
documentHandlingStatus = prop;
}

bool hasMorePages = false; //assume there are no more pages

if (documentHandlingSelect != null) //may not exist on flatbed
scanner but required for feeder
{
//check for document feeder
int feederFlag =
unchecked((int)documentHandlingSelect.get_Value());

if ((feederFlag & WIA_DPS_DOCUMENT_HANDLING_SELECT_FEEDER)
!= 0)
{
int feedReadyFlag =
unchecked((int)documentHandlingStatus.get_Value());
hasMorePages = ((feedReadyFlag &
WIA_DPS_DOCUMENT_HANDLING_STATUS_FEED_READY) != 0);
}
}

return hasMorePages;
}

}
}


I am getting Object reference not set to an instance of an object...

Use the "new" keyword to create an object instance

This is on the line img[ScanCount] =
(ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatJPEG);

I have a breakpoint in on that line. It breaks, I click step into, the
scanner then scans and partially ejects the last document, but then I get
a green break on that line with the above error.

If I try to step again, I get the green break on the same line with "Value
does not fall within the expected range"

Step again, the project stopped, but the scanner is still saying
"Scanning"

I have found some VB.NET code and I am trying to convert it to C# and to
fit my application. The above code is my test application so that I can
give you as much working code as I can.

The VB.NET code is at http://www.xtremevbtalk.com/showthread.php?t=288758
(message 8). While mine is slightly different, I have tried to implement
some of what it is suggesting.

Also, I am not sure if I am disposing of the WIA object properly, I have
tried a number of things, which includes the Marshal.ReleaseComObject and
also just setting the object to null. Now, this is an area I am not
familiar at all.

The scanner is a HP Scanjet N6350, network scanner with an ADF. I need to
be able to scan all the documents via the ADF, as mentioned above, the
scanItem.Transfer will trigger the scan, I have 3 docs loaded and it
passes all docs through but partially holds onto the third, whilst still
saying "Scanning" on the scanner panel.



Like always, any help or pointers would be very much appreciated.

--
Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
 
P

Peter Duniho

David said:
Hello,

I know that WIA is not everyones speciality. Unfortunately, there is not a
lot of info on the net about using it within .NET and what I do find is not
quite suitable for what I am trying to achieve.

However, my main question here is am I using COM correctly? Am I closing it
down properly so that I can re-use it later?

I would say that, as a general rule, if you need to dispose an object,
even a COM object, you would use the Dispose() method. COM interop is
supposed to handle the COM reference counting on our behalf. I would
think that the ReleaseComObject() method would be needed only when for
some reason you are dealing with extra ref counts outside of the single
count you get when you create a COM object via COM interop in .NET.

That said, surely either would work, and in any case, unless the COM
server has a requirement that only one instance of the object ever
exists at any given time, I don't know why failing to release one
instance would prevent another from being created. That kind of
requirement is unusual.

In fact, based on the docs for ReleaseComObject(), which point out that
if you try to use a COM object _after_ it's been release, you'll get a
NullReferenceException, and since that's the exception you're getting,
my first thought is that maybe you are releasing the COM object too
soon. In other words, yes…you have an object lifetime bug, but it's the
other way. That is, you're releasing it when you shouldn't, rather than
not releasing it when you should.

Unfortunately, from the code example it's not really clear how that
would happen, especially with respect to the line you call out as the
problematic one. I suppose one explanation might be that you are
debugging a "Release" build of the program, and so there's not a precise
correlation between the program line and the actual call stack (the
green-highlighted line is trying to tell you that's a line in the call
stack during the exception, but not the actual line where the exception
occurred…the actual line would be marked in yellow).

The code as posted seems like it has an obvious null reference problem.
But as noted above, a green highlight should mean the exception is
actually occurring lower in the call stack. So your description seems
inconsistent with the apparent problem (i.e. I'd expect yellow
highlighting in the "RunScan()" method, not green).

That said, I'll point out the apparent problem and you can figure out if
it's a real one or not: your code appears to be trying to use the "img"
local variable in the "RunScan()" method without the variable ever being
initialized (it's initialized to "null", rather than an actual array
instance).

It's also not clear to me why it's valid to always release the
"scanItem" object, even if it is a COM object you get from the Scanner
object. I don't know the specifics about the Scanner object, but I
wouldn't expect a simple indexer retrieval to add-ref the interface
returned. Are you sure it does?

And of course, releasing the "img" variable when it's only ever null
would be pointless at best, and wrong at worst (the docs say
ReleaseComObject() will throw an ArgumentException if you pass it null).

It is always the case that without a concise-but-complete code example
it can be difficult or impossible to determine a problem in someone
else's code, and I think that's especially true in this particular
context. I realize there are probably a lot of prerequisites to
executing this code, but the fact is, without being able to see the
exception "live" it's hard to know for sure what we're looking at. :(

Pete
 
D

David

Hi Peter,

The sample I posted is the whole code, there is nothing missing apart from
the form design and the program.cs. The code as is is exactly as I selected
all, then copied/pasted. I don't know what else I can add to it to make a
full and complete sample.

There are 2 buttons on the form. One is to select the source (this should be
done to ensure you are using the correct scanner and should be done prior to
scanning). The other is to run the scan.

If it is missing something, then I am missing something in the development,
but I don't know what, which I guess is partly what I am asking for.

It appears that none of the WIA objects has a dispose method. Some of the C#
samples I have seen have been using the ReleaseComObject to release (after
checking that it is not null first)


I have initialised the img now... ImageFile img = new ImageFile[50];

(The sheet feeder has a max sheet count of 50)

I have removed the ReleaseComObject lines as well.

What is really odd now is that the scan will proceed, though still stops and
holds onto the third sheet. I have to press the cancel butto on the scanner
itself, but it still hold the sheet and I have to pull it out.

I am single stepping... each step is highlighted in yellow (as I expect)

The first picture is saved in the first loop, so the first run is OK. The
second loop will stop on the scanItem.Transfer with a green highlight. (The
yellow highlight was on that line immediately prior to stepping, as soon as
I stepped, it green highlighted)

The call stack is as follows...

[Managed to Native Transition]
Scan.exe!Scan.Test.RunScan() Line 91 + 0x14 bytes C#
Scan.exe!Scan.Test.button1_Click(object sender = {Text = "Scan"},
System.EventArgs e = {X = 0x00000089 Y = 0x0000000c Button = Left}) Line 52
+ 0x7 bytes C#
System.Windows.Forms.dll!System.Windows.Forms.Control.OnClick(System.EventArgs
e) + 0x6a bytes
System.Windows.Forms.dll!System.Windows.Forms.Button.OnClick(System.EventArgs
e) + 0x49 bytes
System.Windows.Forms.dll!System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs
mevent = {X = 0x00000089 Y = 0x0000000c Button = Left}) + 0xc8 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseUp(ref
System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button,
int clicks) + 0x2f7 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref
System.Windows.Forms.Message m) + 0x526 bytes
System.Windows.Forms.dll!System.Windows.Forms.ButtonBase.WndProc(ref
System.Windows.Forms.Message m) + 0xc7 bytes
System.Windows.Forms.dll!System.Windows.Forms.Button.WndProc(ref
System.Windows.Forms.Message m) + 0x2b bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref
System.Windows.Forms.Message m) + 0xd bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref
System.Windows.Forms.Message m) + 0x36 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr
hWnd, int msg = 0x00000202, System.IntPtr wparam, System.IntPtr lparam) +
0x57 bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int
dwComponentID, int reason = 0xffffffff, int pvLoopData = 0x00000000) + 0x2f1
bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int
reason = 0xffffffff, System.Windows.Forms.ApplicationContext context =
{System.Windows.Forms.ApplicationContext}) + 0x17d bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int
reason, System.Windows.Forms.ApplicationContext context) + 0x53 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form
mainForm) + 0x2e bytes
Scan.exe!Scan.Program.Main() Line 18 + 0x1a bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile,
System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x39
bytes
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
+ 0x2b bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object
state) + 0x3b bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext
executionContext, System.Threading.ContextCallback callback, object state) +
0x81 bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes


So, I cannot proceed after I have a green highlight, so I have to stop the
debugging and click the cancel button on the scanner and pull out the third
sheet. I then stack the sheets again and run the program again, single
stepping.

The scanner then clicks but doesn't scan, however, the program still runs
and when it saves the image, it is now actually the second image from the
ADF that is saved. So, to me, there is something with the scanItem.Trasnfer
line again. The current green message is "Value does not fall within the
expected range". Single stepping then goes into the Dispose of the
Test.Designer.cs then studio stops debugging.

It is now at this point that I have to reboot the computer as nothing will
work anymore.

--
Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
 
P

Peter Duniho

David said:
Hi Peter,

The sample I posted is the whole code, there is nothing missing apart from
the form design and the program.cs. The code as is is exactly as I selected
all, then copied/pasted. I don't know what else I can add to it to make a
full and complete sample.

You may find these links helpful:
http://www.yoda.arachsys.com/csharp/complete.html
http://www.yoda.arachsys.com/csharp/incomplete.html
http://sscce.org/

I don't even know if WIA is available on any random Windows computer or
if that's something people need to install before using. But even
ignoring the WIA question, the code you posted won't compile, never mind
run, without the addition of at least some code. In addition, there
appears to be parts of the code that are unnecessary for the purpose of
reproducing the problem you're seeing.
There are 2 buttons on the form. One is to select the source (this should be
done to ensure you are using the correct scanner and should be done prior to
scanning). The other is to run the scan.

If it is missing something, then I am missing something in the development,
but I don't know what, which I guess is partly what I am asking for.

It appears that none of the WIA objects has a dispose method. Some of the C#
samples I have seen have been using the ReleaseComObject to release (after
checking that it is not null first)

Okay. As I've mentioned before (not necessarily in threads you're
following), I'm not an expert on COM, never mind COM interop in .NET.
I'd assumed that every RCW would include an implementation of
IDisposable. Note that you may have to cast the COM object instance to
IDisposable to call Dispose(); it might be an explicit implementation
rather than implicit.

But I suppose it's possible not every COM interop object in .NET
implements IDisposable.
I have initialised the img now... ImageFile img = new ImageFile[50];

And did your null reference exception go away?
(The sheet feeder has a max sheet count of 50)

How is that relevant? Why do we need to know the max sheet count of the
sheet feeder? What if we have a scanner without a sheet feeder, or no
scanner at all?
I have removed the ReleaseComObject lines as well.

What is really odd now is that the scan will proceed, though still stops and
holds onto the third sheet. I have to press the cancel butto on the scanner
itself, but it still hold the sheet and I have to pull it out.

I am single stepping... each step is highlighted in yellow (as I expect)

The first picture is saved in the first loop, so the first run is OK. The
second loop will stop on the scanItem.Transfer with a green highlight. (The
yellow highlight was on that line immediately prior to stepping, as soon as
I stepped, it green highlighted)

The call stack is as follows...

[Managed to Native Transition]
Scan.exe!Scan.Test.RunScan() Line 91 + 0x14 bytes C#
Scan.exe!Scan.Test.button1_Click(object sender = {Text = "Scan"},
System.EventArgs e = {X = 0x00000089 Y = 0x0000000c Button = Left}) Line 52
+ 0x7 bytes C#
[...]

So, in other words, your code is stuck in the native code for the COM
object. I think it's highly unlikely that this is specifically a C#
question, and you will thus be highly unlikely to receive a correct
answer to the question in this newsgroup.

It could happen, but you are probably much better off separating the
question into two parts: the WIA part and the C#/COM interop part.
Until you fully understand all the issues around the WIA part (i.e.
you're able to write from scratch unmanaged code that handles the WIA
interface), trying to figure out the COM interop side at the same time
will be much harder.

Even once you then start working on the COM interop side, I believe that
the general purpose .NET interop newsgroup would be a better resource
than this one.

I'm sorry I don't have much specific to offer. It's just that this
question is really off-topic in this newsgroup, which means that those
of us reading it really have very little expertise related to the
question itself and so have very little useful to say on the matter.

As you can see, I have plenty of non-useful things to say. But you
should probably seek experts in the domain specific to your problem. :)

Pete
 
T

Tim Roberts

David said:
I am having problems with the WIA Com object and I am not sure what I am
doing with it...
....
private void RunScan()
{
int ScanCount = 0;
bool ReadyForScan = IsPaperInFeeder();
ImageFile[] img = null; // = new ImageFile[]();

while (ReadyForScan)
{
WIA.Item scanItem = Scanner.Items[1];

img[ScanCount] =
(ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatJPEG);
int FrameCount = img[ScanCount].FrameCount;

This code, as it is, is going to fail because "img" is null when you go to
assign the first item. If you need to create a dynamically-sized list of
objects, you should ust a List.
List<ImageFile> img = new List<ImageFile>();
while( ReadyForScan )
{
....
img.Add( scanItem.Transfer(WIA.FormatID.wiaFormatJPEG) );
 
T

Tim Roberts

Peter Duniho said:
I don't even know if WIA is available on any random Windows computer or
if that's something people need to install before using.

WIA was built-in starting in Windows 98 and Windows 2000. However, it's
only meaningful if a WIA device is present (scanner or camera).
 
Joined
Aug 12, 2010
Messages
1
Reaction score
0
Hi David,


I have the same problem as you ("the scanner then scans and partially ejects the last document"). Are you solve the problem?? I have Scanjet N6310, and I don't find the solution.

Thank you.


David said:
Hi all,

I am having problems with the WIA Com object and I am not sure what I am
doing with it...



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WIA;
using System.Runtime.InteropServices;
using System.Configuration;

namespace Scan
{
public partial class Test : Form
{
private const int WIA_DPS_DOCUMENT_HANDLING_SELECT_FEEDER = 1;
private const int WIA_DPS_DOCUMENT_HANDLING_SELECT_FLATBED = 2;

private const int WIA_DPS_DOCUMENT_HANDLING_STATUS_FEED_READY = 1;

private const int WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS = 1024;
private const int WIA_PROPERTIES_WIA_DIP_FIRST = 2;
private const int WIA_PROPERTIES_WIA_DPA_FIRST =
WIA_PROPERTIES_WIA_DIP_FIRST + WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS;
private const int WIA_PROPERTIES_WIA_DPC_FIRST =
WIA_PROPERTIES_WIA_DPA_FIRST + WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS;

private const int WIA_PROPERTIES_WIA_DPS_FIRST =
WIA_PROPERTIES_WIA_DPC_FIRST + WIA_PROPERTIES_WIA_RESERVED_FOR_NEW_PROPS;

private Object WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_STATUS =
WIA_PROPERTIES_WIA_DPS_FIRST + 13;
private Object WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_SELECT =
WIA_PROPERTIES_WIA_DPS_FIRST + 14;


WIA.CommonDialog dlg = new WIA.CommonDialogClass();
Device Scanner;


public Test()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
RunScan();
}

private void Test_FormClosed(object sender, FormClosedEventArgs e)
{
if (dlg != null)
Marshal.ReleaseComObject(dlg);
if (Scanner != null)
Marshal.ReleaseComObject(Scanner);
}

private void Test_Load(object sender, EventArgs e)
{

}

private void button2_Click(object sender, EventArgs e)
{
Scanner =
dlg.ShowSelectDevice(WiaDeviceType.UnspecifiedDeviceType, true, false);
}

private void RunScan()
{
int ScanCount = 0;
bool ReadyForScan = IsPaperInFeeder();
ImageFile[] img = null; // = new ImageFile[]();

while (ReadyForScan)
{

WIA.Item scanItem = Scanner.Items[1];

img[ScanCount] =
(ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatJPEG);
int FrameCount = img[ScanCount].FrameCount;

ReadyForScan = IsPaperInFeeder();

string scanTime = DateTime.Now.ToFileTime().ToString();

string FileName = "c:\\tempimage_" + scanTime + ".jpg";

img[ScanCount].SaveFile(FileName);


Marshal.ReleaseComObject(scanItem);

ScanCount++;
}
Marshal.ReleaseComObject(img);
}

public bool IsPaperInFeeder()
{
if (Scanner == null) throw new Exception("Scanner device must be
selected and connected!");

//get the two properties
Property documentHandlingSelect = null;
Property documentHandlingStatus = null;

//foreach (Property prop in Device.Properties)
foreach (Property prop in Scanner.Properties)
{
if (prop.PropertyID ==
(int)WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_SELECT)
documentHandlingSelect = prop;
if (prop.PropertyID ==
(int)WIA_PROPERTIES_WIA_DPS_DOCUMENT_HANDLING_STATUS)
documentHandlingStatus = prop;
}

bool hasMorePages = false; //assume there are no more pages

if (documentHandlingSelect != null) //may not exist on flatbed
scanner but required for feeder
{
//check for document feeder
int feederFlag =
unchecked((int)documentHandlingSelect.get_Value());

if ((feederFlag & WIA_DPS_DOCUMENT_HANDLING_SELECT_FEEDER)
!= 0)
{
int feedReadyFlag =
unchecked((int)documentHandlingStatus.get_Value());
hasMorePages = ((feedReadyFlag &
WIA_DPS_DOCUMENT_HANDLING_STATUS_FEED_READY) != 0);
}
}

return hasMorePages;
}

}
}


I am getting Object reference not set to an instance of an object...

Use the "new" keyword to create an object instance

This is on the line img[ScanCount] =
(ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatJPEG);

I have a breakpoint in on that line. It breaks, I click step into, the
scanner then scans and partially ejects the last document, but then I get a
green break on that line with the above error.

If I try to step again, I get the green break on the same line with "Value
does not fall within the expected range"

Step again, the project stopped, but the scanner is still saying "Scanning"

I have found some VB.NET code and I am trying to convert it to C# and to fit
my application. The above code is my test application so that I can give you
as much working code as I can.

The VB.NET code is at http://www.xtremevbtalk.com/showthread.php?t=288758
(message 8). While mine is slightly different, I have tried to implement
some of what it is suggesting.

Also, I am not sure if I am disposing of the WIA object properly, I have
tried a number of things, which includes the Marshal.ReleaseComObject and
also just setting the object to null. Now, this is an area I am not familiar
at all.

The scanner is a HP Scanjet N6350, network scanner with an ADF. I need to be
able to scan all the documents via the ADF, as mentioned above, the
scanItem.Transfer will trigger the scan, I have 3 docs loaded and it passes
all docs through but partially holds onto the third, whilst still saying
"Scanning" on the scanner panel.



Like always, any help or pointers would be very much appreciated.

--
Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top