Should now catch error before first transfer and during transfer loop as a possible #57 fix.

This commit is contained in:
Eugene Wang 2016-02-20 06:50:11 -05:00
parent 870ecd64a4
commit b603dd7f59
4 changed files with 143 additions and 73 deletions

View File

@ -85,6 +85,15 @@ namespace NTwain
/// </summary>
bool IsTransferring { get; }
/// <summary>
/// Whether to stop the transfer process when transfer error is encountered.
/// May be required on some sources.
/// </summary>
/// <value>
/// <c>true</c> to stop on transfer error; otherwise, <c>false</c>.
/// </value>
bool StopOnTransferError { get; set; }
/// <summary>
/// Try to show the built-in source selector dialog and return the selected source.
/// This is not recommended and is only included for completeness.

View File

@ -45,63 +45,89 @@ namespace NTwain.Internals
var pending = new TWPendingXfers();
var rc = session.DGControl.PendingXfers.Get(pending);
do
if (rc == ReturnCode.Success)
{
#region raise xfer ready
var preXferArgs = new TransferReadyEventArgs(session.CurrentSource, pending.Count, pending.EndOfJob); ;
session.SafeSyncableRaiseEvent(preXferArgs);
#endregion
#region actually handle xfer
if (preXferArgs.CancelAll)
do
{
rc = session.DGControl.PendingXfers.Reset(pending);
}
else
{
if (!preXferArgs.CancelCurrent)
#region raise xfer ready
var preXferArgs = new TransferReadyEventArgs(session.CurrentSource, pending.Count, pending.EndOfJob); ;
session.SafeSyncableRaiseEvent(preXferArgs);
#endregion
#region actually handle xfer
if (preXferArgs.CancelAll)
{
if (xferImage)
rc = session.DGControl.PendingXfers.Reset(pending);
}
else
{
if (!preXferArgs.CancelCurrent)
{
switch (imgXferMech)
if (xferImage)
{
case XferMech.Memory:
DoImageMemoryXfer(session);
break;
case XferMech.File:
DoImageFileXfer(session);
break;
case XferMech.MemFile:
DoImageMemoryFileXfer(session);
break;
case XferMech.Native:
default: // always assume native
DoImageNativeXfer(session);
break;
switch (imgXferMech)
{
case XferMech.Memory:
rc = DoImageMemoryXfer(session);
break;
case XferMech.File:
rc = DoImageFileXfer(session);
break;
case XferMech.MemFile:
rc = DoImageMemoryFileXfer(session);
break;
case XferMech.Native:
default: // always assume native
rc = DoImageNativeXfer(session);
break;
}
}
if (xferAudio)
{
switch (audXferMech)
{
case XferMech.File:
rc = DoAudioFileXfer(session);
break;
case XferMech.Native:
default: // always assume native
rc = DoAudioNativeXfer(session);
break;
}
}
}
if (xferAudio)
switch (rc)
{
switch (audXferMech)
{
case XferMech.File:
DoAudioFileXfer(session);
break;
case XferMech.Native:
default: // always assume native
DoAudioNativeXfer(session);
break;
}
case ReturnCode.Cancel:
default:
// as usual
rc = session.DGControl.PendingXfers.EndXfer(pending);
break;
}
if (rc != ReturnCode.Success && session.StopOnTransferError)
{
// end xfer without setting rc to exit (good/bad?)
session.DGControl.PendingXfers.EndXfer(pending);
}
else
{
rc = session.DGControl.PendingXfers.EndXfer(pending);
}
}
rc = session.DGControl.PendingXfers.EndXfer(pending);
}
#endregion
#endregion
} while (rc == ReturnCode.Success && pending.Count != 0);
} while (rc == ReturnCode.Success && pending.Count != 0);
}
else
{
HandleReturnCode(session, rc);
}
// some poorly written scanner drivers return failure on EndXfer so also check for pending count now.
// this may break with other sources but we'll see
@ -112,15 +138,32 @@ namespace NTwain.Internals
}
}
private static void HandleReturnCode(ITwainSessionInternal session, ReturnCode rc)
{
switch (rc)
{
case ReturnCode.Success:
case ReturnCode.XferDone:
case ReturnCode.Cancel:
// ok to keep going
break;
default:
var status = session.CurrentSource.GetStatus();
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(rc, status));
break;
}
}
#region audio xfers
static void DoAudioNativeXfer(ITwainSessionInternal session)
static ReturnCode DoAudioNativeXfer(ITwainSessionInternal session)
{
IntPtr dataPtr = IntPtr.Zero;
IntPtr lockedPtr = IntPtr.Zero;
ReturnCode xrc = ReturnCode.Failure;
try
{
var xrc = session.DGAudio.AudioNativeXfer.Get(ref dataPtr);
xrc = session.DGAudio.AudioNativeXfer.Get(ref dataPtr);
if (xrc == ReturnCode.XferDone)
{
session.ChangeState(7, true);
@ -133,7 +176,7 @@ namespace NTwain.Internals
}
else
{
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
HandleReturnCode(session, xrc);
}
}
catch (Exception ex)
@ -156,39 +199,43 @@ namespace NTwain.Internals
dataPtr = IntPtr.Zero;
}
}
return xrc;
}
static void DoAudioFileXfer(ITwainSessionInternal session)
static ReturnCode DoAudioFileXfer(ITwainSessionInternal session)
{
string filePath = null;
TWSetupFileXfer setupInfo;
if (session.DGControl.SetupFileXfer.Get(out setupInfo) == ReturnCode.Success)
ReturnCode xrc = session.DGControl.SetupFileXfer.Get(out setupInfo);
if (xrc == ReturnCode.Success)
{
filePath = setupInfo.FileName;
}
var xrc = session.DGAudio.AudioFileXfer.Get();
if (xrc == ReturnCode.XferDone)
{
session.SafeSyncableRaiseEvent(new DataTransferredEventArgs(session.CurrentSource, filePath, (FileFormat)0));
}
else
{
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
xrc = session.DGAudio.AudioFileXfer.Get();
if (xrc == ReturnCode.XferDone)
{
session.SafeSyncableRaiseEvent(new DataTransferredEventArgs(session.CurrentSource, filePath, (FileFormat)0));
}
else
{
HandleReturnCode(session, xrc);
}
}
return xrc;
}
#endregion
#region image xfers
static void DoImageNativeXfer(ITwainSessionInternal session)
static ReturnCode DoImageNativeXfer(ITwainSessionInternal session)
{
IntPtr dataPtr = IntPtr.Zero;
IntPtr lockedPtr = IntPtr.Zero;
ReturnCode xrc = ReturnCode.Failure;
try
{
var xrc = session.DGImage.ImageNativeXfer.Get(ref dataPtr);
xrc = session.DGImage.ImageNativeXfer.Get(ref dataPtr);
if (xrc == ReturnCode.XferDone)
{
session.ChangeState(7, true);
@ -200,7 +247,7 @@ namespace NTwain.Internals
}
else
{
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
HandleReturnCode(session, xrc);
}
}
catch (Exception ex)
@ -223,9 +270,10 @@ namespace NTwain.Internals
dataPtr = IntPtr.Zero;
}
}
return xrc;
}
static void DoImageFileXfer(ITwainSessionInternal session)
static ReturnCode DoImageFileXfer(ITwainSessionInternal session)
{
string filePath = null;
TWSetupFileXfer setupInfo;
@ -241,14 +289,16 @@ namespace NTwain.Internals
}
else
{
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
HandleReturnCode(session, xrc);
}
return xrc;
}
static void DoImageMemoryXfer(ITwainSessionInternal session)
static ReturnCode DoImageMemoryXfer(ITwainSessionInternal session)
{
TWSetupMemXfer memInfo;
if (session.DGControl.SetupMemXfer.Get(out memInfo) == ReturnCode.Success)
ReturnCode xrc = session.DGControl.SetupMemXfer.Get(out memInfo);
if (xrc == ReturnCode.Success)
{
TWImageMemXfer xferInfo = new TWImageMemXfer();
try
@ -269,7 +319,6 @@ namespace NTwain.Internals
// todo: use array instead of memory stream?
using (MemoryStream xferredData = new MemoryStream())
{
var xrc = ReturnCode.Success;
do
{
xrc = session.DGImage.ImageMemXfer.Get(xferInfo);
@ -305,7 +354,7 @@ namespace NTwain.Internals
}
else
{
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
HandleReturnCode(session, xrc);
}
}
}
@ -323,13 +372,15 @@ namespace NTwain.Internals
}
}
return xrc;
}
static void DoImageMemoryFileXfer(ITwainSessionInternal session)
static ReturnCode DoImageMemoryFileXfer(ITwainSessionInternal session)
{
// since it's memory-file xfer need info from both (maybe)
TWSetupMemXfer memInfo;
TWSetupFileXfer fileInfo;
ReturnCode xrc = ReturnCode.Failure;
if (session.DGControl.SetupMemXfer.Get(out memInfo) == ReturnCode.Success &&
session.DGControl.SetupFileXfer.Get(out fileInfo) == ReturnCode.Success)
{
@ -346,7 +397,7 @@ namespace NTwain.Internals
TheMem = PlatformInfo.Current.MemoryManager.Allocate(memInfo.Preferred)
};
var xrc = ReturnCode.Success;
xrc = ReturnCode.Success;
using (var outStream = File.OpenWrite(tempFile))
{
do
@ -385,7 +436,7 @@ namespace NTwain.Internals
}
else
{
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
HandleReturnCode(session, xrc);
}
}
catch (Exception ex)
@ -410,6 +461,7 @@ namespace NTwain.Internals
DoImageXferredEventRoutine(session, IntPtr.Zero, null, finalFile, fileInfo.Format);
}
}
return xrc;
}
static void DoImageXferredEventRoutine(ITwainSessionInternal session, IntPtr dataPtr, byte[] dataArray, string filePath, FileFormat format)

View File

@ -23,7 +23,7 @@ namespace NTwain
/// <summary>
/// The build release version number.
/// </summary>
public const string Build = "3.3.8"; // change this for each nuget release
public const string Build = "3.3.9"; // change this for each nuget release
}

View File

@ -202,6 +202,15 @@ namespace NTwain
/// </summary>
public bool IsTransferring { get { return State > 5; } }
/// <summary>
/// Whether to stop the transfer process when transfer error is encountered.
/// May be required on some sources.
/// </summary>
/// <value>
/// <c>true</c> to stop on transfer error; otherwise, <c>false</c>.
/// </value>
public bool StopOnTransferError { get; set; }
/// <summary>
/// Opens the data source manager. This must be the first method used
/// before using other TWAIN functions. Calls to this must be followed by