mirror of
https://github.com/soukoku/ntwain.git
synced 2025-08-20 09:50:50 +08:00
Should now catch error before first transfer and during transfer loop as a possible #57 fix.
This commit is contained in:
parent
870ecd64a4
commit
b603dd7f59
@ -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.
|
||||||
|
|||||||
@ -45,63 +45,89 @@ 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);
|
||||||
do
|
if (rc == ReturnCode.Success)
|
||||||
{
|
{
|
||||||
#region raise xfer ready
|
do
|
||||||
|
|
||||||
var preXferArgs = new TransferReadyEventArgs(session.CurrentSource, pending.Count, pending.EndOfJob); ;
|
|
||||||
session.SafeSyncableRaiseEvent(preXferArgs);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region actually handle xfer
|
|
||||||
|
|
||||||
if (preXferArgs.CancelAll)
|
|
||||||
{
|
{
|
||||||
rc = session.DGControl.PendingXfers.Reset(pending);
|
#region raise xfer ready
|
||||||
}
|
|
||||||
else
|
var preXferArgs = new TransferReadyEventArgs(session.CurrentSource, pending.Count, pending.EndOfJob); ;
|
||||||
{
|
session.SafeSyncableRaiseEvent(preXferArgs);
|
||||||
if (!preXferArgs.CancelCurrent)
|
|
||||||
|
#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:
|
switch (imgXferMech)
|
||||||
DoImageMemoryXfer(session);
|
{
|
||||||
break;
|
case XferMech.Memory:
|
||||||
case XferMech.File:
|
rc = DoImageMemoryXfer(session);
|
||||||
DoImageFileXfer(session);
|
break;
|
||||||
break;
|
case XferMech.File:
|
||||||
case XferMech.MemFile:
|
rc = DoImageFileXfer(session);
|
||||||
DoImageMemoryFileXfer(session);
|
break;
|
||||||
break;
|
case XferMech.MemFile:
|
||||||
case XferMech.Native:
|
rc = DoImageMemoryFileXfer(session);
|
||||||
default: // always assume native
|
break;
|
||||||
DoImageNativeXfer(session);
|
case XferMech.Native:
|
||||||
break;
|
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 ReturnCode.Cancel:
|
||||||
{
|
default:
|
||||||
case XferMech.File:
|
// as usual
|
||||||
DoAudioFileXfer(session);
|
rc = session.DGControl.PendingXfers.EndXfer(pending);
|
||||||
break;
|
break;
|
||||||
case XferMech.Native:
|
}
|
||||||
default: // always assume native
|
|
||||||
DoAudioNativeXfer(session);
|
if (rc != ReturnCode.Success && session.StopOnTransferError)
|
||||||
break;
|
{
|
||||||
}
|
// 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.
|
// 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)
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user