I don't think you can use TWAIN without a window. You're going to run into that problem in the console and the service. You won't be able to use windows forms but you could P/invoke CreateWindow/CreateWindowEx from User32.dll and perhaps use that.
... inside service or program class:
IntPtr32 _handle;
... inside start up function somewhere
if (string.IsNullOrEmpty(className))
className = "TwainWindow";
_wndProc = WndProc;
var wndclass = new WNDCLASS();
wndclass.lpszClassName = className;
wndclass.lpfnWndProc = _wndProc;
var classAtom = RegisterClassW(ref wndclass);
var lastError = Marshal.GetLastWin32Error();
if (classAtom == 0 && lastError != ERROR_CLASS_ALREADY_EXISTS)
{
throw new Exception("Could not register window class");
}
_handle = CreateWindowExW(
0,
wndclass.lpszClassName,
String.Empty,
0,
0,
0,
0,
0,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero
);
}
That should create an invisible window
I didn't post the complete code here because there's quite a bit to it, but you can try using my MessageWindow class to create an invisible hwnd for you.
It's in this code.
Understanding Windows Message Queues for the C# Developer[
^]
You'll have to modify the WindowProc (i think it's called) window procedure in that code. I'll bet you a dollar TWAIN will send special messages to that routine which you'll treat as TWAIN "events" and process them. If it doesn't do that then the TWAIN libraries themselves create a UI and you are out of luck.
I haven't tested the idea within the service: Usually to create *visible* windows you must allow your service to interact with the desktop. I *think* invisible windows are fine.