mirror of
https://github.com/soukoku/ntwain.git
synced 2025-04-29 07:10:28 +08:00
Added SetTwainDirectTask method to session.
This commit is contained in:
parent
d9e56794e5
commit
714caf4935
@ -4,6 +4,7 @@
|
||||
<PackageId>NTwain</PackageId>
|
||||
<Description>Library containing the TWAIN API for dotnet.</Description>
|
||||
<TargetFrameworks>net45;netstandard2.0;</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -49,6 +49,19 @@ namespace TWAINWorkingGroup
|
||||
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>
|
||||
/// A more dotnet-friendly representation of <see cref="TW_ENUMERATION"/>.
|
||||
/// </summary>
|
||||
|
@ -131,16 +131,16 @@ namespace NTwain
|
||||
get { return _twain.GetState(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the manager status. Useful after getting a non-success return code.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TW_STATUS GetStatus()
|
||||
{
|
||||
TW_STATUS stat = default;
|
||||
_ = _twain.DatStatus(DG.CONTROL, MSG.GET, ref stat);
|
||||
return stat;
|
||||
}
|
||||
///// <summary>
|
||||
///// Gets the manager status. Useful after getting a non-success return code.
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//public TW_STATUS GetStatus()
|
||||
//{
|
||||
// TW_STATUS stat = default;
|
||||
// _ = _twain.DatStatus(DG.CONTROL, MSG.GET, ref stat);
|
||||
// return stat;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the TWAIN data source manager.
|
||||
@ -352,12 +352,36 @@ namespace NTwain
|
||||
return new Metrics { ReturnCode = sts };
|
||||
}
|
||||
|
||||
//public sts SetTwainDirectTask()
|
||||
//{
|
||||
// TW_TWAINDIRECT task = default;
|
||||
// var sts = _twain.DatTwaindirect(DG.CONTROL, MSG.SETTASK, ref task);
|
||||
// return sts;
|
||||
//}
|
||||
/// <summary>
|
||||
/// Sends a TWAIN Direct task from the application to the driver.
|
||||
/// </summary>
|
||||
/// <param name="taskJson">The TWAIN Direct task in JSON.</param>
|
||||
/// <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
|
||||
}
|
||||
|
@ -14,6 +14,30 @@ namespace NTwain
|
||||
/// </summary>
|
||||
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()
|
||||
|
||||
public static TValue ReadOneValueContainer<TValue>(TWAIN twain, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
|
||||
|
@ -13,6 +13,45 @@ namespace NTwain
|
||||
/// </summary>
|
||||
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()
|
||||
|
||||
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
|
||||
{
|
||||
var type = typeof(TValue);
|
||||
|
Loading…
Reference in New Issue
Block a user