mirror of
https://github.com/soukoku/ntwain.git
synced 2025-04-29 10:20:32 +08:00
Added SetTwainDirectTask method to session.
This commit is contained in:
parent
d9e56794e5
commit
714caf4935
@ -4,6 +4,7 @@
|
|||||||
<PackageId>NTwain</PackageId>
|
<PackageId>NTwain</PackageId>
|
||||||
<Description>Library containing the TWAIN API for dotnet.</Description>
|
<Description>Library containing the TWAIN API for dotnet.</Description>
|
||||||
<TargetFrameworks>net45;netstandard2.0;</TargetFrameworks>
|
<TargetFrameworks>net45;netstandard2.0;</TargetFrameworks>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -49,6 +49,19 @@ namespace TWAINWorkingGroup
|
|||||||
public int Images;
|
public int Images;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct TwainDirectTaskResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Return code of task.
|
||||||
|
/// </summary>
|
||||||
|
public STS ReturnCode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The response of the task in JSON if successful.
|
||||||
|
/// </summary>
|
||||||
|
public string ResponseJson;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A more dotnet-friendly representation of <see cref="TW_ENUMERATION"/>.
|
/// A more dotnet-friendly representation of <see cref="TW_ENUMERATION"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -131,16 +131,16 @@ namespace NTwain
|
|||||||
get { return _twain.GetState(); }
|
get { return _twain.GetState(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// Gets the manager status. Useful after getting a non-success return code.
|
///// Gets the manager status. Useful after getting a non-success return code.
|
||||||
/// </summary>
|
///// </summary>
|
||||||
/// <returns></returns>
|
///// <returns></returns>
|
||||||
public TW_STATUS GetStatus()
|
//public TW_STATUS GetStatus()
|
||||||
{
|
//{
|
||||||
TW_STATUS stat = default;
|
// TW_STATUS stat = default;
|
||||||
_ = _twain.DatStatus(DG.CONTROL, MSG.GET, ref stat);
|
// _ = _twain.DatStatus(DG.CONTROL, MSG.GET, ref stat);
|
||||||
return stat;
|
// return stat;
|
||||||
}
|
//}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the TWAIN data source manager.
|
/// Opens the TWAIN data source manager.
|
||||||
@ -352,12 +352,36 @@ namespace NTwain
|
|||||||
return new Metrics { ReturnCode = sts };
|
return new Metrics { ReturnCode = sts };
|
||||||
}
|
}
|
||||||
|
|
||||||
//public sts SetTwainDirectTask()
|
/// <summary>
|
||||||
//{
|
/// Sends a TWAIN Direct task from the application to the driver.
|
||||||
// TW_TWAINDIRECT task = default;
|
/// </summary>
|
||||||
// var sts = _twain.DatTwaindirect(DG.CONTROL, MSG.SETTASK, ref task);
|
/// <param name="taskJson">The TWAIN Direct task in JSON.</param>
|
||||||
// return sts;
|
/// <param name="communicationManager">The current system being used to connect the application to the scanner.</param>
|
||||||
//}
|
/// <returns></returns>
|
||||||
|
public TwainDirectTaskResult SetTwainDirectTask(string taskJson, ushort communicationManager = 0)
|
||||||
|
{
|
||||||
|
var result = new TwainDirectTaskResult { ReturnCode = STS.FAILURE };
|
||||||
|
TW_TWAINDIRECT task = default;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
task.SizeOf = (uint)Marshal.SizeOf(typeof(TW_TWAINDIRECT));
|
||||||
|
task.CommunicationManager = communicationManager;
|
||||||
|
task.Send = ValueWriter.StringToPtrUTF8(_twain, taskJson, out int length);
|
||||||
|
task.SendSize = (uint)length;
|
||||||
|
|
||||||
|
result.ReturnCode = _twain.DatTwaindirect(DG.CONTROL, MSG.SETTASK, ref task);
|
||||||
|
if (result.ReturnCode == STS.SUCCESS && task.ReceiveSize > 0 && task.Receive != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
result.ResponseJson = ValueReader.PtrToStringUTF8(task.Receive, (int)task.ReceiveSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (task.Send != IntPtr.Zero) _twain.DsmMemFree(ref task.Send); // just in case
|
||||||
|
if (task.Receive != IntPtr.Zero) _twain.DsmMemFree(ref task.Receive);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,30 @@ namespace NTwain
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ValueReader
|
public static class ValueReader
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Reads pointer as UTF8 string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="intPtr">Pointer to string.</param>
|
||||||
|
/// <param name="length">Number of bytes to read.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static unsafe string PtrToStringUTF8(IntPtr intPtr, int length)
|
||||||
|
{
|
||||||
|
if (intPtr == IntPtr.Zero) throw new ArgumentNullException(nameof(intPtr));
|
||||||
|
if (length == 0) throw new ArgumentOutOfRangeException(nameof(length), length, "Length must be greater than 0.");
|
||||||
|
|
||||||
|
//// safe method with 2 copies
|
||||||
|
//var bytes = new byte[length];
|
||||||
|
//Marshal.Copy(intPtr, bytes, 0, length);
|
||||||
|
//return Encoding.UTF8.GetString(bytes);
|
||||||
|
|
||||||
|
// unsafe method with 1 copy (does it work?)
|
||||||
|
sbyte* bytes = (sbyte*)intPtr;
|
||||||
|
var str = new string(bytes, 0, length, Encoding.UTF8);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// most of these are modified from the original TWAIN.CapabilityToCsv()
|
// most of these are modified from the original TWAIN.CapabilityToCsv()
|
||||||
|
|
||||||
public static TValue ReadOneValueContainer<TValue>(TWAIN twain, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
|
public static TValue ReadOneValueContainer<TValue>(TWAIN twain, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
|
||||||
|
@ -13,6 +13,45 @@ namespace NTwain
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ValueWriter
|
public static class ValueWriter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Allocates and copies the string value into a pointer in UTF8 that's null-terminated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="twain"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="length">Actual number of bytes used to encode the string without the null.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static unsafe IntPtr StringToPtrUTF8(TWAIN twain, string value, out int length)
|
||||||
|
{
|
||||||
|
var utf8 = Encoding.UTF8;
|
||||||
|
length = utf8.GetByteCount(value);
|
||||||
|
|
||||||
|
var ptr = twain.DsmMemAlloc((uint)length + 1); // +1 for null-terminated
|
||||||
|
|
||||||
|
// TODO: test if this works
|
||||||
|
int written;
|
||||||
|
byte* bytes = (byte*)ptr;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fixed (char* firstChar = value)
|
||||||
|
{
|
||||||
|
written = Encoding.UTF8.GetBytes(firstChar, value.Length, bytes, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes[written] = 0;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// just in case
|
||||||
|
if (ptr != IntPtr.Zero) twain.DsmMemFree(ref ptr);
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// most of these are modified from the original TWAIN.CsvToCapability()
|
// most of these are modified from the original TWAIN.CsvToCapability()
|
||||||
|
|
||||||
public static void WriteOneValueContainer<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, TValue value) where TValue : struct
|
public static void WriteOneValueContainer<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, TValue value) where TValue : struct
|
||||||
@ -470,7 +509,6 @@ namespace NTwain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static TWTY GetItemType<TValue>() where TValue : struct
|
static TWTY GetItemType<TValue>() where TValue : struct
|
||||||
{
|
{
|
||||||
var type = typeof(TValue);
|
var type = typeof(TValue);
|
||||||
|
Loading…
Reference in New Issue
Block a user