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> /// </summary>
bool IsTransferring { get; } 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> /// <summary>
/// Try to show the built-in source selector dialog and return the selected source. /// Try to show the built-in source selector dialog and return the selected source.
/// This is not recommended and is only included for completeness. /// This is not recommended and is only included for completeness.

View File

@@ -45,6 +45,8 @@ namespace NTwain.Internals
var pending = new TWPendingXfers(); var pending = new TWPendingXfers();
var rc = session.DGControl.PendingXfers.Get(pending); var rc = session.DGControl.PendingXfers.Get(pending);
if (rc == ReturnCode.Success)
{
do do
{ {
#region raise xfer ready #region raise xfer ready
@@ -69,17 +71,17 @@ namespace NTwain.Internals
switch (imgXferMech) switch (imgXferMech)
{ {
case XferMech.Memory: case XferMech.Memory:
DoImageMemoryXfer(session); rc = DoImageMemoryXfer(session);
break; break;
case XferMech.File: case XferMech.File:
DoImageFileXfer(session); rc = DoImageFileXfer(session);
break; break;
case XferMech.MemFile: case XferMech.MemFile:
DoImageMemoryFileXfer(session); rc = DoImageMemoryFileXfer(session);
break; break;
case XferMech.Native: case XferMech.Native:
default: // always assume native default: // always assume native
DoImageNativeXfer(session); rc = DoImageNativeXfer(session);
break; break;
} }
} }
@@ -88,20 +90,44 @@ namespace NTwain.Internals
switch (audXferMech) switch (audXferMech)
{ {
case XferMech.File: case XferMech.File:
DoAudioFileXfer(session); rc = DoAudioFileXfer(session);
break; break;
case XferMech.Native: case XferMech.Native:
default: // always assume native default: // always assume native
DoAudioNativeXfer(session); rc = DoAudioNativeXfer(session);
break; break;
} }
} }
} }
switch (rc)
{
case ReturnCode.Cancel:
default:
// as usual
rc = session.DGControl.PendingXfers.EndXfer(pending); 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);
}
} }
#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. // 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 // 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 #region audio xfers
static void DoAudioNativeXfer(ITwainSessionInternal session) static ReturnCode DoAudioNativeXfer(ITwainSessionInternal session)
{ {
IntPtr dataPtr = IntPtr.Zero; IntPtr dataPtr = IntPtr.Zero;
IntPtr lockedPtr = IntPtr.Zero; IntPtr lockedPtr = IntPtr.Zero;
ReturnCode xrc = ReturnCode.Failure;
try try
{ {
var xrc = session.DGAudio.AudioNativeXfer.Get(ref dataPtr); xrc = session.DGAudio.AudioNativeXfer.Get(ref dataPtr);
if (xrc == ReturnCode.XferDone) if (xrc == ReturnCode.XferDone)
{ {
session.ChangeState(7, true); session.ChangeState(7, true);
@@ -133,7 +176,7 @@ namespace NTwain.Internals
} }
else else
{ {
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus())); HandleReturnCode(session, xrc);
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -156,39 +199,43 @@ namespace NTwain.Internals
dataPtr = IntPtr.Zero; dataPtr = IntPtr.Zero;
} }
} }
return xrc;
} }
static void DoAudioFileXfer(ITwainSessionInternal session) static ReturnCode DoAudioFileXfer(ITwainSessionInternal session)
{ {
string filePath = null; string filePath = null;
TWSetupFileXfer setupInfo; 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; filePath = setupInfo.FileName;
}
var xrc = session.DGAudio.AudioFileXfer.Get(); xrc = session.DGAudio.AudioFileXfer.Get();
if (xrc == ReturnCode.XferDone) if (xrc == ReturnCode.XferDone)
{ {
session.SafeSyncableRaiseEvent(new DataTransferredEventArgs(session.CurrentSource, filePath, (FileFormat)0)); session.SafeSyncableRaiseEvent(new DataTransferredEventArgs(session.CurrentSource, filePath, (FileFormat)0));
} }
else else
{ {
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus())); HandleReturnCode(session, xrc);
} }
} }
return xrc;
}
#endregion #endregion
#region image xfers #region image xfers
static void DoImageNativeXfer(ITwainSessionInternal session) static ReturnCode DoImageNativeXfer(ITwainSessionInternal session)
{ {
IntPtr dataPtr = IntPtr.Zero; IntPtr dataPtr = IntPtr.Zero;
IntPtr lockedPtr = IntPtr.Zero; IntPtr lockedPtr = IntPtr.Zero;
ReturnCode xrc = ReturnCode.Failure;
try try
{ {
var xrc = session.DGImage.ImageNativeXfer.Get(ref dataPtr); xrc = session.DGImage.ImageNativeXfer.Get(ref dataPtr);
if (xrc == ReturnCode.XferDone) if (xrc == ReturnCode.XferDone)
{ {
session.ChangeState(7, true); session.ChangeState(7, true);
@@ -200,7 +247,7 @@ namespace NTwain.Internals
} }
else else
{ {
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus())); HandleReturnCode(session, xrc);
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -223,9 +270,10 @@ namespace NTwain.Internals
dataPtr = IntPtr.Zero; dataPtr = IntPtr.Zero;
} }
} }
return xrc;
} }
static void DoImageFileXfer(ITwainSessionInternal session) static ReturnCode DoImageFileXfer(ITwainSessionInternal session)
{ {
string filePath = null; string filePath = null;
TWSetupFileXfer setupInfo; TWSetupFileXfer setupInfo;
@@ -241,14 +289,16 @@ namespace NTwain.Internals
} }
else 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; 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(); TWImageMemXfer xferInfo = new TWImageMemXfer();
try try
@@ -269,7 +319,6 @@ namespace NTwain.Internals
// todo: use array instead of memory stream? // todo: use array instead of memory stream?
using (MemoryStream xferredData = new MemoryStream()) using (MemoryStream xferredData = new MemoryStream())
{ {
var xrc = ReturnCode.Success;
do do
{ {
xrc = session.DGImage.ImageMemXfer.Get(xferInfo); xrc = session.DGImage.ImageMemXfer.Get(xferInfo);
@@ -305,7 +354,7 @@ namespace NTwain.Internals
} }
else 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) // since it's memory-file xfer need info from both (maybe)
TWSetupMemXfer memInfo; TWSetupMemXfer memInfo;
TWSetupFileXfer fileInfo; TWSetupFileXfer fileInfo;
ReturnCode xrc = ReturnCode.Failure;
if (session.DGControl.SetupMemXfer.Get(out memInfo) == ReturnCode.Success && if (session.DGControl.SetupMemXfer.Get(out memInfo) == ReturnCode.Success &&
session.DGControl.SetupFileXfer.Get(out fileInfo) == ReturnCode.Success) session.DGControl.SetupFileXfer.Get(out fileInfo) == ReturnCode.Success)
{ {
@@ -346,7 +397,7 @@ namespace NTwain.Internals
TheMem = PlatformInfo.Current.MemoryManager.Allocate(memInfo.Preferred) TheMem = PlatformInfo.Current.MemoryManager.Allocate(memInfo.Preferred)
}; };
var xrc = ReturnCode.Success; xrc = ReturnCode.Success;
using (var outStream = File.OpenWrite(tempFile)) using (var outStream = File.OpenWrite(tempFile))
{ {
do do
@@ -385,7 +436,7 @@ namespace NTwain.Internals
} }
else else
{ {
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus())); HandleReturnCode(session, xrc);
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -410,6 +461,7 @@ namespace NTwain.Internals
DoImageXferredEventRoutine(session, IntPtr.Zero, null, finalFile, fileInfo.Format); DoImageXferredEventRoutine(session, IntPtr.Zero, null, finalFile, fileInfo.Format);
} }
} }
return xrc;
} }
static void DoImageXferredEventRoutine(ITwainSessionInternal session, IntPtr dataPtr, byte[] dataArray, string filePath, FileFormat format) static void DoImageXferredEventRoutine(ITwainSessionInternal session, IntPtr dataPtr, byte[] dataArray, string filePath, FileFormat format)

View File

@@ -23,7 +23,7 @@ namespace NTwain
/// <summary> /// <summary>
/// The build release version number. /// The build release version number.
/// </summary> /// </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> /// </summary>
public bool IsTransferring { get { return State > 5; } } 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> /// <summary>
/// Opens the data source manager. This must be the first method used /// Opens the data source manager. This must be the first method used
/// before using other TWAIN functions. Calls to this must be followed by /// before using other TWAIN functions. Calls to this must be followed by