/// <summary> /// Send an encryption report to the scanner and show the results... /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void m_buttonGetEncryptionReport_Click(object sender, EventArgs e) { bool blSuccess; long lJsonErrorIndex = 0; ApiCmd apicmd; JsonLookup jsonlookup; // Issue the command... apicmd = new ApiCmd(m_dnssddeviceinfo); m_twainlocalscannerclient.ClientScannerSendTask("{\"actions\":[{\"action\":\"encryptionReport\"}]}", ref apicmd); blSuccess = m_twainlocalscannerclient.ClientCheckForApiErrors("ClientScannerSendTask", ref apicmd); if (!blSuccess) { MessageBox.Show("Command failed...", Config.GetResource(m_resourcemanager, "strFormScanTitle")); return; } // Parse the JSON... jsonlookup = new JsonLookup(); blSuccess = jsonlookup.Load(apicmd.GetHttpResponseData(), out lJsonErrorIndex); if (!blSuccess) { MessageBox.Show("JSON error at: " + lJsonErrorIndex, Config.GetResource(m_resourcemanager, "strFormScanTitle")); return; } // Show the result... string szTask = jsonlookup.Get("results.session.task"); if (!string.IsNullOrEmpty(szTask)) { MessageBox.Show(szTask, Config.GetResource(m_resourcemanager, "strFormScanTitle")); } }
/// <summary> /// Load data from a file... /// </summary> /// <param name="a_szFile">the file to load it from</param> /// <returns>try if successful</returns> public bool Load(string a_szFile) { try { // No file... if (!File.Exists(a_szFile)) { return(false); } // Parse it... long lResponseCharacterOffset; JsonLookup jsonlookup = new JsonLookup(); jsonlookup.Load(File.ReadAllText(a_szFile), out lResponseCharacterOffset); // Start with a clean slate... m_device = default(Device); // Add the entry... Set ( jsonlookup.Get("scanner.twainLocalTy"), jsonlookup.Get("scanner.twainLocalSerialNumber"), jsonlookup.Get("scanner.twainLocalNote") ); } catch { m_device = default(Device); } // All done... return(true); }
/// <summary> /// Load the configuration object. We want to read in the /// configuaration data (in JSON format) and a list of the /// command line arguments. /// </summary> /// <param name="a_szExecutablePath">the fill path to the program using us</param> /// <param name="a_szCommandLine">key[=value] groupings</param> /// <param name="a_szConfigFile">a JSON file</param> public static bool Load(string a_szExecutablePath, string[] a_aszCommandLine, string a_szConfigFile) { try { // Work out where our executable lives... ms_szExecutablePath = a_szExecutablePath; ms_szExecutableName = Path.GetFileNameWithoutExtension(ms_szExecutablePath); // The read folder is the path to the executable. This is where we're // going to find our appdata.txt file, which contains configuration // information that can be overridden by the user (assuming they have // rights to it). We'll put other readonly stuff here too, like the // certification tests... ms_szReadFolder = Path.GetDirectoryName(ms_szExecutablePath); // The write folder is the path to all of the the files we can update, // which includes image files, metadata, log files, registration/selection // files. This stuff is specific to a user, so by default we're going to // keep it in their %appdata%/twaindirect/executablename folder... ms_szWriteFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); ms_szWriteFolder = Path.Combine(ms_szWriteFolder, "twaindirect"); ms_szWriteFolder = Path.Combine(ms_szWriteFolder, ms_szExecutableName); // Store the command line... ms_aszCommandLine = a_aszCommandLine; // Load the config, we'll first look for a name decorated version // of the file (ex: TwainDirect.Scanner.appdata.txt), and if that // fails, then we'll try appdata.txt... string szConfigFile = Path.Combine(ms_szReadFolder, ms_szExecutableName + "." + a_szConfigFile); if (!File.Exists(szConfigFile)) { szConfigFile = Path.Combine(ms_szReadFolder, a_szConfigFile); } if (File.Exists(szConfigFile)) { long a_lJsonErrorindex; string szConfig = File.ReadAllText(szConfigFile); ms_jsonlookup = new JsonLookup(); ms_jsonlookup.Load(szConfig, out a_lJsonErrorindex); } // Check if the user wants to override the read and write folders... ms_szReadFolder = Get("readFolder", ms_szReadFolder); ms_szWriteFolder = Get("writeFolder", ms_szWriteFolder); // Make sure we have a write folder... if (!Directory.Exists(ms_szWriteFolder)) { Directory.CreateDirectory(ms_szWriteFolder); } } catch { return(false); } // All done... return(true); }
// Public Methods... #region Public Methods... /// <summary> /// Load the configuration object. We want to read in the /// configuaration data (in JSON format) and a list of the /// command line arguments. /// </summary> /// <param name="a_szExecutablePath">the fill path to the program using us</param> /// <param name="a_szCommandLine">key[=value] groupings</param> /// <param name="a_szConfigFile">a JSON file</param> public static bool Load(string a_szExecutablePath, string[] a_aszCommandLine, string a_szConfigFile) { try { // Set up our folders... ms_szExecutablePath = a_szExecutablePath; ms_szExecutableName = Path.GetFileNameWithoutExtension(ms_szExecutablePath); ms_szWriteFolder = ms_szExecutablePath.Split(new string[] { ms_szExecutableName }, StringSplitOptions.None)[0]; ms_szReadFolder = Path.Combine(ms_szWriteFolder, ms_szExecutableName); ms_szWriteFolder = Path.Combine(ms_szWriteFolder, "data"); ms_szWriteFolder = Path.Combine(ms_szWriteFolder, ms_szExecutableName); if (!Directory.Exists(ms_szWriteFolder)) { Directory.CreateDirectory(ms_szWriteFolder); } // Store the command line... ms_aszCommandLine = a_aszCommandLine; // Load the config... string szConfigFile = Path.Combine(ms_szReadFolder, a_szConfigFile); if (File.Exists(szConfigFile)) { long a_lJsonErrorindex; string szConfig = File.ReadAllText(szConfigFile); ms_jsonlookup = new JsonLookup(); ms_jsonlookup.Load(szConfig, out a_lJsonErrorindex); } } catch { return(false); } // All done... return(true); }
/// <summary> /// Run the driver... /// </summary> /// <returns>true on success</returns> public bool Run() { bool blSuccess; bool blRunning = true; bool blSetAppCapabilities = false; long lResponseCharacterOffset; string szJson; string szMeta; string szSession; string szImageBlock; Ipc ipc; SwordTask swordtask; TwainLocalScanner.ApiStatus apistatus; // Pipe mode starting... TwainDirect.Support.Log.Info("IPC mode starting..."); // Set up communication with our server process... ipc = new Ipc(m_szIpc, false, null, null); ipc.MonitorPid(m_iPid); ipc.Connect(); // TBD (hack) string szCapabilities = Sword.SaneListDrivers(); TwainDirect.Support.Log.Info("TwainListDrivers: " + szCapabilities); JsonLookup jsonlookupCapabilities = new JsonLookup(); jsonlookupCapabilities.Load(szCapabilities, out lResponseCharacterOffset); m_szTwainDriverIdentity = jsonlookupCapabilities.Get("scanners[0].sane"); m_szNumberOfSheets = jsonlookupCapabilities.Get("scanners[0].numberOfSheets[1]"); m_szPixelFormat = jsonlookupCapabilities.Get("scanners[0].pixelFormat[0]"); m_szResolution = jsonlookupCapabilities.Get("scanners[0].resolution[0]"); m_iOffsetX = 0; m_iOffsetY = 0; m_iWidth = 0; m_iHeight = 0; int.TryParse(jsonlookupCapabilities.Get("scanners[0].offsetX[0]"), out m_iOffsetX); int.TryParse(jsonlookupCapabilities.Get("scanners[0].offsetY[0]"), out m_iOffsetY); int.TryParse(jsonlookupCapabilities.Get("scanners[0].width[1]"), out m_iWidth); int.TryParse(jsonlookupCapabilities.Get("scanners[0].height[1]"), out m_iHeight); // Loopy... while (blRunning) { // Read a command... szJson = ipc.Read(); if (szJson == null) { TwainDirect.Support.Log.Info("IPC channel disconnected..."); break; } // Log it... //TwainDirect.Support.Log.Info(""); //TwainDirect.Support.Log.Info(szJson); // Parse the command... JsonLookup jsonlookup = new JsonLookup(); if (!jsonlookup.Load(szJson, out lResponseCharacterOffset)) { continue; } // Dispatch the command... switch (jsonlookup.Get("method")) { default: break; case "closeSession": apistatus = DeviceScannerCloseSession(out szSession); if (apistatus == TwainLocalScanner.ApiStatus.success) { blSuccess = ipc.Write ( "{\n" + " \"status\": \"" + apistatus + "\",\n" + szSession + "}" ); } else { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"" + "}" ); } if (!blSuccess) { TwainDirect.Support.Log.Info("IPC channel disconnected..."); blRunning = false; } break; case "createSession": apistatus = DeviceScannerCreateSession(jsonlookup, out szSession); if (apistatus == TwainLocalScanner.ApiStatus.success) { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"," + szSession + "}" ); } else { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"" + "}" ); } if (!blSuccess) { TwainDirect.Support.Log.Info("IPC channel disconnected..."); blRunning = false; } break; case "exit": blRunning = false; break; case "getSession": apistatus = DeviceScannerGetSession(out szSession); if (apistatus == TwainLocalScanner.ApiStatus.success) { blSuccess = ipc.Write ( "{" + "\"status\": \"" + apistatus + "\"," + szSession + "}" ); } else { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"" + "}" ); } if (!blSuccess) { TwainDirect.Support.Log.Info("IPC channel disconnected..."); blRunning = false; } break; case "readImageBlock": apistatus = DeviceScannerReadImageBlock(jsonlookup, out szImageBlock); if (apistatus == TwainLocalScanner.ApiStatus.success) { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"," + "\"imageBlock\":\"" + szImageBlock + "\"" + "}" ); } else { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"" + "}" ); } if (!blSuccess) { TwainDirect.Support.Log.Info("IPC channel disconnected..."); blRunning = false; } break; case "readImageBlockMetadata": apistatus = DeviceScannerReadImageBlockMetadata(jsonlookup, out szMeta); if (apistatus == TwainLocalScanner.ApiStatus.success) { apistatus = DeviceScannerGetSession(out szSession); blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"," + "\"meta\":\"" + szMeta + "\"" + (!string.IsNullOrEmpty(szSession) ? "," + szSession : "") + "}" ); } else { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"" + "}" ); } if (!blSuccess) { TwainDirect.Support.Log.Info("IPC channel disconnected..."); blRunning = false; } break; case "releaseImageBlocks": apistatus = DeviceScannerReleaseImageBlocks(jsonlookup, out szSession); if (apistatus == TwainLocalScanner.ApiStatus.success) { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"," + szSession + "}" ); } else { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"" + "}" ); } if (!blSuccess) { TwainDirect.Support.Log.Info("IPC channel disconnected..."); blRunning = false; } break; case "sendTask": apistatus = DeviceScannerSendTask(jsonlookup, out swordtask, ref blSetAppCapabilities); if (apistatus == TwainLocalScanner.ApiStatus.success) { if (string.IsNullOrEmpty(swordtask.GetTaskReply())) { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"" + "}" ); } else { string szTaskReply = swordtask.GetTaskReply(); blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"," + "\"taskReply\":" + szTaskReply + "}" ); } } else { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\",\n" + "\"exception\":\"" + swordtask.GetException() + "\"," + "\"jsonKey\":\"" + swordtask.GetJsonExceptionKey() + "\"" + "}" ); } if (!blSuccess) { TwainDirect.Support.Log.Info("IPC channel disconnected..."); blRunning = false; } break; case "startCapturing": apistatus = DeviceScannerStartCapturing(ref blSetAppCapabilities, out szSession); if (apistatus == TwainLocalScanner.ApiStatus.success) { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"," + szSession + "}" ); } else { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"" + "}" ); } if (!blSuccess) { TwainDirect.Support.Log.Info("IPC channel disconnected..."); blRunning = false; } break; case "stopCapturing": apistatus = DeviceScannerStopCapturing(out szSession); if (apistatus == TwainLocalScanner.ApiStatus.success) { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"," + szSession + "}" ); } else { blSuccess = ipc.Write ( "{" + "\"status\":\"" + apistatus + "\"" + "}" ); } if (!blSuccess) { TwainDirect.Support.Log.Info("IPC channel disconnected..."); blRunning = false; } break; } } // All done... TwainDirect.Support.Log.Info("IPC mode completed..."); return(true); }
/////////////////////////////////////////////////////////////////////////////// // Protected Methods (ServiceBase overrides)... /////////////////////////////////////////////////////////////////////////////// #region Protected Methods (ServiceBase overrides)... /// <summary> /// Register... /// /// TBD: Obviously this needs a way to communicate with /// the user other than console stuff, so fix that... /// </summary> /// <param name="a_iCommand"></param> protected override void OnCustomCommand(int a_iCommand) { int iScanner; long lResponseCharacterOffset; string szScanners; string szNumber; string szText; JsonLookup jsonlookup; ApiCmd apicmd; // Turn the buttons off... Display("Looking for Scanners..."); // Get the list of scanners... szScanners = m_scanner.GetAvailableScanners("getproductnames", ""); if (szScanners == null) { Display("No scanners found..."); return; } try { jsonlookup = new JsonLookup(); jsonlookup.Load(szScanners, out lResponseCharacterOffset); } catch { Display("No scanners found..."); return; } // Show all the scanners, and then ask for the number of // the one to use as the new default... szText = ""; for (iScanner = 0; ; iScanner++) { // Get the next scanner... string szScanner = jsonlookup.Get("scanners[" + iScanner + "].twidentityProductName"); if (string.IsNullOrEmpty(szScanner)) { szScanner = jsonlookup.Get("scanners[" + iScanner + "].sane"); } // We're out of stuff... if (string.IsNullOrEmpty(szScanner)) { break; } // If this is the current default, make a note of it... if (m_scanner.GetTwainLocalTy() == szScanner) { szText = (iScanner + 1) + ": " + szScanner + " ***DEFAULT***"; Display(szText); } // Otherwise, just list it... else { Display((iScanner + 1) + ": " + szScanner); } } // Finish the text for the prompt... if (string.IsNullOrEmpty(szText)) { szText = "Enter a number from 1 to " + iScanner + Environment.NewLine + "(there is no current default)"; } else { szText = "Enter a number from 1 to " + iScanner + Environment.NewLine + szText; } // Select the default... int iNumber = 0; for (; ;) { // Prompt the user... szNumber = ""; bool blOk = InputBox ( "Select Default Scanner", szText, ref szNumber ); // The user wants out... if (!blOk) { Display("Canceled..."); break; } // Check the result... if (!int.TryParse(szNumber, out iNumber)) { Display("Please enter a number in the range 1 to " + iScanner); continue; } // Check the range... if ((iNumber < 1) || (iNumber > iScanner)) { Display("Please enter a number in the range 1 to " + iScanner); continue; } // We have what we want... break; } // Do a deep inquiry on the selected scanner... szScanners = m_scanner.GetAvailableScanners("getinquiry", jsonlookup.Get("scanners[" + (iScanner - 1) + "].twidentityProductName")); if (szScanners == null) { Display("We are unable to use the selected scanner..."); return; } try { jsonlookup = new JsonLookup(); jsonlookup.Load(szScanners, out lResponseCharacterOffset); } catch { Display("We are unable to use the selected scanner..."); return; } // See if the user wants to update their note... string szNote = m_scanner.GetTwainLocalNote(); if ((iNumber >= 1) && (iNumber <= iScanner)) { bool blOk = InputBox ( "Enter Note", "Your current note is: " + m_scanner.GetTwainLocalNote() + Environment.NewLine + "Type a new note, or just press the Enter key to keep what you have.", ref szNote ); if (string.IsNullOrEmpty(szNote)) { szNote = m_scanner.GetTwainLocalNote(); } } // Register it, make a note if it works by clearing the // no devices flag... apicmd = new ApiCmd(); if (m_scanner.RegisterScanner(jsonlookup, 0, szNote, ref apicmd)) { m_blNoDevices = false; Display("Done..."); } else { Display("Registration failed for: " + iNumber); } // Prompt... Display("Press the enter key to finish..."); Console.In.ReadLine(); }
/// <summary> /// Register a device for use... /// </summary> public void Register() { int iScanner; long lResponseCharacterOffset; string szScanners; string szNumber; string szText; JsonLookup jsonlookup; ApiCmd apicmd; // Prompt the user to turn on their scanner, we don't care // about the result... szText = ""; Display(Environment.NewLine); InputBox ( "Power-On Scanner:", "Please turn your TWAIN scanner on, when it's ready press the ENTER key...", ref szText ); // Turn the buttons off... Display(Environment.NewLine); Display("Registering (please wait, if there are a lot of scanner drivers, this can take a while)..."); // Get the list of scanners... szScanners = m_scanner.GetAvailableScanners(); if (string.IsNullOrEmpty(szScanners)) { Display("No devices found..."); return; } try { jsonlookup = new JsonLookup(); jsonlookup.Load(szScanners, out lResponseCharacterOffset); } catch { Display("No devices found..."); return; } // Show all the scanners, and then ask for the number of // the one to use as the new default... szText = ""; int iNumber = 0; for (iScanner = 0; ; iScanner++) { // Get the next scanner... string szScanner = jsonlookup.Get("scanners[" + iScanner + "].twidentity"); if (string.IsNullOrEmpty(szScanner)) { szScanner = jsonlookup.Get("scanners[" + iScanner + "].sane"); } // We're out of stuff... if (string.IsNullOrEmpty(szScanner)) { break; } // If this is the current default, make a note of it... if (m_scanner.GetTwainLocalTy() == szScanner) { Display((iScanner + 1) + ": " + szScanner + " ***DEFAULT***"); iNumber = iScanner + 1; } // Otherwise, just list it... else { Display((iScanner + 1) + ": " + szScanner); } } // Build the text for the prompt... if (iScanner == 1) { szText = "Enter 1 to select this scanner." + Environment.NewLine + "Enter 0 to disable the system." + Environment.NewLine + "Enter by itself (with no number) keeps the current setting."; } else if (iScanner == 2) { szText = "Enter 1 or 2 to select a scanner." + Environment.NewLine + "Enter 0 to disable the system." + Environment.NewLine + "Enter by itself (with no number) keeps the current setting."; } else { szText = "Enter a number from 1 to " + iScanner + " to select a scanner." + Environment.NewLine + "Enter 0 to disable the system." + Environment.NewLine + "Enter by itself (with no number) keeps the current setting."; } // Have the user select a scanner... for (;;) { // Prompt the user... szNumber = ""; Display(Environment.NewLine); bool blOk = InputBox ( "Select Default Scanner:", szText, ref szNumber ); // The user wants out... if (!blOk) { break; } // Check the result... if (!int.TryParse(szNumber, out iNumber)) { Display("That wasn't a number..."); continue; } // Check the range... if ((iNumber < 0) || (iNumber > iScanner)) { Display("Please enter a valid number..."); continue; } // We have what we want... break; } // See if the user wants to update their note... string szNote = m_scanner.GetTwainLocalNote(); if ((iNumber >= 1) && (iNumber <= iScanner)) { Display(Environment.NewLine); bool blOk = InputBox ( "Enter Note:", (string.IsNullOrEmpty(m_scanner.GetTwainLocalNote()) ? "You have no note." : "Your current note is: " + m_scanner.GetTwainLocalNote()) + Environment.NewLine + "Type a new note, or just press the Enter key to keep what you have.", ref szNote ); if (string.IsNullOrEmpty(szNote)) { szNote = m_scanner.GetTwainLocalNote(); } } // Register it, make a note if it works by clearing the // no devices flag... apicmd = new ApiCmd(null); if (m_scanner.RegisterScanner(jsonlookup, iNumber - 1, szNote, ref apicmd)) { m_blNoDevices = false; Display("Done..."); } else { Display("Registration failed for: " + iNumber); } // Prompt... Display(Environment.NewLine); Display("Press the enter key to finish..."); Console.In.ReadLine(); }
/// <summary> /// Monitor for work... /// </summary> /// <param name="sender"></param> internal void MonitorTasks(object sender) { bool blSuccess; string szJson; string szDeviceName; long lResponseCharacterOffset; XmppCallback xmppcallback = (XmppCallback)sender; JsonLookup jsonlookup = new JsonLookup(); TwainLocalScanner.Command command; // Load the data... if (jsonlookup.Load(xmppcallback.m_szData, out lResponseCharacterOffset)) { // Check out the event type... string szType = jsonlookup.Get("type"); if (szType == null) { Log.Error("XMPP event received has no type in it..."); Log.Error(xmppcallback.m_szData); return; } // Our event types... switch (szType) { // // Nope, gots no clue... // default: Display(""); Display("Unrecognized command: " + szType); Log.Error("XMPP event has unrecognized type..."); Log.Error(xmppcallback.m_szData); return; // // Our command has been canceled, we have to acknowledge that // and either kill it or let it finish. We opt to kill. In // the worst case scenerio we'll try to update a canceled // command some place else in the code. We need to be able // to handle that pressure anyways... // case "COMMAND_CANCELED": case "COMMAND_CANCELLED": Display(""); Display("Command cancelled..."); szJson = jsonlookup.Get("method"); if (string.IsNullOrEmpty(szJson)) { blSuccess = jsonlookup.Load(szJson, out lResponseCharacterOffset); if (blSuccess) { ApiCmd apicmd = new ApiCmd(null); //apicmd.SetState("canceled", null); } } return; // // Our command has expired, we don't need to take any additional // action, because to get this far we must never have seen or // acknowledged the command... // case "COMMAND_EXPIRED": Display(""); Display("Command expired..."); Log.Error("XMPP event COMMAND_EXPIRED..."); Log.Error(xmppcallback.m_szData); return; // // Not supported yet... // case "DEVICE_ACL_UPDATED": Display(""); Display("ACL updated..."); Log.Error("XMPP event DEVICE_ACL_UPDATED not supported yet..."); Log.Error(xmppcallback.m_szData); return; // // Somebody doesn't like us anymore... // case "DEVICE_DELETED": // Well, we'd better stop... MonitorTasksStop(); Display(""); Display("Stop (a device has been deleted)..."); // Refresh our device list... Thread.Sleep(1000); bool blNoDevices = RefreshDeviceList(); // Notify the caller... if (m_stopnotification != null) { m_stopnotification(blNoDevices); } return; // // We have something new to work on, drop down so that we're // not doing all this work in the switch statement... // case "COMMAND_CREATED": break; } // The command was included in the notification, so let's start // doing work with it. We'll begin by collecting some info... string szState = jsonlookup.Get("command.state"); string szDeviceId = jsonlookup.Get("deviceId"); // Find the match in our list... szDeviceName = m_twainlocalscanner.GetTwainLocalTy(); // Did we find it? if (!string.IsNullOrEmpty(szDeviceName)) { // Build the command... command = new TwainLocalScanner.Command(); command.szDeviceName = szDeviceName; command.szJson = jsonlookup.Get("method"); // Display it... switch (m_iDiagnostics) { default: break; case 1: if (command.szJson.Contains("readImageBlock") && command.szJson.Contains("Metadata")) { Display("Sending an image..."); } else if (command.szJson.Contains("startCapturing")) { Display(" "); Display("Scanning started..."); } else if (command.szJson.Contains("stopCapturing")) { Display("Scanning stopped..."); } else if (command.szJson.Contains("createSession")) { Display(" "); Display("*** Scanner locked ***"); } else if (command.szJson.Contains("closeSession")) { Display(" "); Display("*** Scanner unlocked ***"); } break; case 2: Display(" "); Display("XMPP"); Display(command.szDeviceName + ": " + command.szJson); break; } // Dispatch it... //m_twainlocalscanner.DeviceDispatchCommand(command, ref httplistenercontext); } } }
/// <summary> /// Register a device for use... /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void m_buttonRegister_Click(object sender, EventArgs e) { int iScanner; long lResponseCharacterOffset; string szNumber; string szScanners; string szText; JsonLookup jsonlookup; ApiCmd apicmd; DialogResult dialogresult; // Are you sure? dialogresult = MessageBox.Show("Do you want to register a TWAIN driver? Please note that depending on how many drivers are installed, this may take a while.", "Register", MessageBoxButtons.YesNo); if (dialogresult == DialogResult.No) { return; } // Turn the buttons off... SetButtons(ButtonState.Undefined); Display(""); Display("Looking for Scanners (please wait, this can take a while)..."); // Get the list of scanners... szScanners = m_scanner.GetAvailableScanners(); if (szScanners == null) { Display("No devices found..."); return; } try { jsonlookup = new JsonLookup(); jsonlookup.Load(szScanners, out lResponseCharacterOffset); } catch { Display("No devices found..."); return; } // Show all the scanners, and then ask for the number of // the one to use as the new default... szText = ""; for (iScanner = 0;; iScanner++) { // Get the next scanner... string szScanner = jsonlookup.Get("scanners[" + iScanner + "].twidentityProductName"); if (string.IsNullOrEmpty(szScanner)) { szScanner = jsonlookup.Get("scanners[" + iScanner + "].sane"); } // We're out of stuff... if (string.IsNullOrEmpty(szScanner)) { break; } // If this is the current default, make a note of it... if (m_scanner.GetTwainLocalTy() == szScanner) { szText = (iScanner + 1) + ": " + szScanner + " ***DEFAULT***"; Display(szText); } // Otherwise, just list it... else { Display((iScanner + 1) + ": " + szScanner); } } // Finish the text for the prompt... if (string.IsNullOrEmpty(szText)) { szText = "Enter a number from 1 to " + iScanner + Environment.NewLine + "(there is no current default)" + iScanner; } else { szText = "Enter a number from 1 to " + iScanner + Environment.NewLine + szText; } // Select the default... int iNumber = 0; for (;;) { // Prompt the user... szNumber = ""; dialogresult = InputBox ( "Select Default Scanner", szText, ref szNumber ); // The user wants out... if (dialogresult != DialogResult.OK) { Display("Canceled..."); break; } // Check the result... if (!int.TryParse(szNumber, out iNumber)) { Display("Please enter a number in the range 1 to " + iScanner); continue; } // Check the range... if ((iNumber < 1) || (iNumber > iScanner)) { Display("Please enter a number in the range 1 to " + iScanner); continue; } // We have what we want... break; } // See if the user wants to update their note... string szNote = m_scanner.GetTwainLocalNote(); if ((iNumber >= 1) && (iNumber <= iScanner)) { dialogresult = InputBox ( "Enter Note", "Your current note is: " + m_scanner.GetTwainLocalNote() + Environment.NewLine + "Type a new note, or just press the Enter key to keep what you have.", ref szNote ); // The user wants out... if ((dialogresult != DialogResult.OK) || string.IsNullOrEmpty(szNote)) { szNote = m_scanner.GetTwainLocalNote(); } } // Register it, make a note if it works by clearing the // no devices flag... apicmd = new ApiCmd(); if (m_scanner.RegisterScanner(jsonlookup, iNumber - 1, szNote, ref apicmd)) { m_blNoDevices = false; Display("Done..."); } else { Display("Registration failed for: " + iNumber); } // Fix the buttons... Display("Registration done..."); if (m_blNoDevices) { SetButtons(ButtonState.NoDevices); } else { SetButtons(ButtonState.WaitingForStart); } }
/// <summary> /// Select the TWAIN driver to use... /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void SelectScanner() { int iScanner; long lResponseCharacterOffset; string szScanners; string szText; JsonLookup jsonlookup; ApiCmd apicmd; List <string> lszDrivers = new List <string>(); // Turn the buttons off... SetButtons(ButtonState.Undefined); Display(""); Display(Config.GetResource(m_resourcemanager, "errLookingForScanners")); // Get the list of scanners... szScanners = m_scanner.GetAvailableScanners("getproductnames", ""); if (szScanners == null) { Display(Config.GetResource(m_resourcemanager, "errNoScannersFound")); SetButtons(ButtonState.NoDevices); return; } try { jsonlookup = new JsonLookup(); jsonlookup.Load(szScanners, out lResponseCharacterOffset); } catch { Display(Config.GetResource(m_resourcemanager, "errNoScannersFound")); SetButtons(ButtonState.NoDevices); return; } // Show all the scanners, and then ask for the number of // the one to use as the new default... szText = ""; string szMessage = ""; string szDefault = ""; for (iScanner = 0; ; iScanner++) { // Get the next scanner... string szScanner = jsonlookup.Get("scanners[" + iScanner + "].twidentityProductName"); if (string.IsNullOrEmpty(szScanner)) { szScanner = jsonlookup.Get("scanners[" + iScanner + "].sane"); } // We're out of stuff... if (string.IsNullOrEmpty(szScanner)) { break; } // If this is the current default, make a note of it... lszDrivers.Add(szScanner); if (m_scanner.GetTwainLocalTy() == szScanner) { szMessage += (iScanner + 1) + ": " + szScanner + " ***DEFAULT***" + Environment.NewLine; szText = (iScanner + 1) + ": " + szScanner + " ***DEFAULT***"; szDefault = szScanner; Display(szText); } // Otherwise, just list it... else { szMessage += (iScanner + 1) + ": " + szScanner + Environment.NewLine; Display((iScanner + 1) + ": " + szScanner); } } // Ask the user to pick a scanner... FormSelect formselect = new FormSelect(m_resourcemanager, lszDrivers, szDefault, m_scanner.GetTwainLocalNote()); formselect.ShowDialog(); int iNumber = formselect.GetSelectedDriver(); string szNote = formselect.GetNote(); if (iNumber < 0) { Display(""); Display(Config.GetResource(m_resourcemanager, "errNoScannersFound")); SetButtons(ButtonState.NoDevices); return; } // A little sleight of hand to get a busy cursor... this.Refresh(); Cursor.Current = Cursors.WaitCursor; this.Refresh(); // Tell the user what we're up to... Display(""); Display("We're going to ask the scanner some questions."); Display("This may take a minute..."); // A little sleight of hand to get a busy cursor... this.Refresh(); Cursor.Current = Cursors.WaitCursor; this.Refresh(); // Do a deep inquiry on the selected scanner... szScanners = m_scanner.GetAvailableScanners("getinquiry", jsonlookup.Get("scanners[" + iNumber + "].twidentityProductName")); if (string.IsNullOrEmpty(szScanners)) { // We are unable to use the selected scanner. Please make sure your scanner is turned on and connected before trying again. Display(""); Display(Config.GetResource(m_resourcemanager, "errUnableToUseScanner")); MessageBox.Show(Config.GetResource(m_resourcemanager, "errUnableToUseScanner"), Config.GetResource(m_resourcemanager, "strFormMainTitle")); SetButtons(ButtonState.NoDevices); Cursor.Current = Cursors.Default; return; } try { jsonlookup = new JsonLookup(); jsonlookup.Load(szScanners, out lResponseCharacterOffset); } catch { Display(""); Display(Config.GetResource(m_resourcemanager, "errUnableToUseScanner")); MessageBox.Show(Config.GetResource(m_resourcemanager, "errUnableToUseScanner"), Config.GetResource(m_resourcemanager, "strFormMainTitle")); SetButtons(ButtonState.NoDevices); Cursor.Current = Cursors.Default; return; } // Register it, make a note if it works by clearing the // no devices flag. Note that the way things work now // there is only ever one scanner in the list... apicmd = new ApiCmd(); if (m_scanner.RegisterScanner(jsonlookup, 0, szNote, ref apicmd)) { m_blNoDevices = false; Display("Done..."); } else { Display("Registration failed for: " + iNumber); MessageBox.Show("Registration failed for: " + iNumber, "Error"); } // Fix the buttons... Display("Registration done..."); if (m_blNoDevices) { SetButtons(ButtonState.NoDevices); } else { SetButtons(ButtonState.WaitingForStart); } }
/// <summary> /// Test our ability to run the TWAIN driver using the TWAIN Direct Client-Scanner API /// as the controlling API. This is easier to debug than running stuff /// across more than one process with the cloud involved... /// </summary> /// <returns></returns> public bool Test() { int ii; int[] aiImageBlockNum; long lResponseCharacterOffset; bool blSts; bool blEndOfJob; string szJson; Thread thread; Ipc ipc; JsonLookup jsonlookup; // Create our objects... m_twainlocalonsane = new TwainLocalOnSane(m_szWriteFolder, m_szIpc, Process.GetCurrentProcess().Id); jsonlookup = new JsonLookup(); ipc = new Ipc(m_szIpc, true); // Run in a thread... thread = new Thread(RunTest); thread.Start(); // Wait for a connection... ipc.Accept(); // Create Session... #region Create Session... // Open the scanner... blSts = ipc.Write ( "{" + "\"method\":\"createSession\"," + "\"scanner\":\"" + m_szScanner + "\"" + "}" ); if (!blSts) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Get the result... szJson = ipc.Read(); // Analyze the result... try { jsonlookup.Load(szJson, out lResponseCharacterOffset); if (jsonlookup.Get("status") != "success") { TwainDirectSupport.Log.Error("createSession failed: " + jsonlookup.Get("status")); return(false); } } catch { TwainDirectSupport.Log.Error("createSession failed: JSON error"); return(false); } #endregion // Set TWAIN Direct Options... #region Set TWAIN Direct Options... string szTwainDirectOptions = File.ReadAllText(m_szTask); blSts = ipc.Write ( "{" + "\"method\":\"setTwainDirectOptions\"," + "\"task\":" + szTwainDirectOptions + "}" ); if (!blSts) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Get the result... szJson = ipc.Read(); if (szJson == null) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } #endregion // Start Capturing... #region Start Capturing... blSts = ipc.Write ( "{" + "\"method\":\"startCapturing\"" + "}" ); if (!blSts) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Get the result... szJson = ipc.Read(); if (szJson == null) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } #endregion // Loop until we run out of images... blEndOfJob = false; aiImageBlockNum = null; while (true) { // Get Session (wait for image)... #region GetSession (wait for images)... // Stay in this loop unti we get an image or an error... while (true) { // Get the current session info... blSts = ipc.Write ( "{" + "\"method\":\"getSession\"" + "}" ); if (!blSts) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Get the result... szJson = ipc.Read(); if (szJson == null) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Parse it... jsonlookup = new JsonLookup(); jsonlookup.Load(szJson, out lResponseCharacterOffset); // Bail if we're end of job... if (jsonlookup.Get("endOfJob") == "true") { blEndOfJob = true; break; } // Collect the data... try { aiImageBlockNum = null; for (ii = 0; ; ii++) { // Get the data... string szNum = jsonlookup.Get("session.imageBlocks[" + ii + "]"); if ((szNum == null) || (szNum == "")) { break; } // Convert it... int iTmp = int.Parse(szNum); // Add it to the list... if (aiImageBlockNum == null) { aiImageBlockNum = new int[1]; aiImageBlockNum[0] = iTmp; } else { int[] aiTmp = new int[aiImageBlockNum.Length + 1]; aiImageBlockNum.CopyTo(aiTmp, 0); aiTmp[aiTmp.Length - 1] = iTmp; aiImageBlockNum = aiTmp; } } } catch { // don't need to do anything... } // We got one! if (aiImageBlockNum != null) { break; } // Snooze a bit... Thread.Sleep(100); } // Bail if we're end of job... if (blEndOfJob) { break; } #endregion // Read Image Block Metadata... #region Read Image Block Metadata... // Get this image's metadata... blSts = ipc.Write ( "{" + "\"method\":\"readImageBlockMetadata\"," + "\"imageBlockNum\":" + aiImageBlockNum[0] + "}" ); if (!blSts) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Get the result... szJson = ipc.Read(); if (szJson == null) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } #endregion // Read Image Block... #region Read Image Block... // Get this image... blSts = ipc.Write ( "{" + "\"method\":\"readImageBlock\"," + "\"imageBlockNum\":" + aiImageBlockNum[0] + "}" ); if (!blSts) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Get the result... szJson = ipc.Read(); if (szJson == null) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } #endregion // Release Image Block... #region Release Image Block... // Release this image... blSts = ipc.Write ( "{" + "\"method\":\"releaseImageBlocks\"," + "\"imageBlockNum\":" + aiImageBlockNum[0] + "," + "\"lastImageBlockNum\":" + aiImageBlockNum[0] + "}" ); if (!blSts) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Get the result... szJson = ipc.Read(); if (szJson == null) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } #endregion } // Stop Capturing... #region Stop Capturing... blSts = ipc.Write ( "{" + "\"method\":\"stopCapturing\"" + "}" ); if (!blSts) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Get the result... szJson = ipc.Read(); if (szJson == null) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } #endregion // Close Session... #region Close Session... // Close the scanner... blSts = ipc.Write ( "{" + "\"method\":\"closeSession\"" + "}" ); if (!blSts) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Get the result... szJson = ipc.Read(); if (szJson == null) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } // Exit the process... blSts = ipc.Write ( "{" + "\"method\":\"exit\"" + "}" ); if (!blSts) { TwainDirectSupport.Log.Error("Lost our process..."); goto ABORT; } #endregion // All done... ABORT: thread.Join(); return(true); }
/// <summary> /// Register a device for use... /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void m_buttonRegister_Click(object sender, EventArgs e) { int iScanner; long lResponseCharacterOffset; string szNumber; string szScanners; string szText; JsonLookup jsonlookup; ApiCmd apicmd; DialogResult dialogresult; // Are you sure? // Do you want to register a TWAIN driver? If so, please make sure your scanner is powered on and connected, and press YES. dialogresult = MessageBox.Show ( Config.GetResource(m_resourcemanager, "errRegisterTwainDriver"), Config.GetResource(m_resourcemanager, "strFormMainTitle"), MessageBoxButtons.YesNo ); if (dialogresult == DialogResult.No) { return; } // Turn the buttons off... SetButtons(ButtonState.Undefined); Display(""); Display(Config.GetResource(m_resourcemanager, "errLookingForScanners")); // Get the list of scanners... szScanners = m_scanner.GetAvailableScanners("getproductnames", ""); if (szScanners == null) { Display(Config.GetResource(m_resourcemanager, "errNoScannersFound")); SetButtons(ButtonState.NoDevices); return; } try { jsonlookup = new JsonLookup(); jsonlookup.Load(szScanners, out lResponseCharacterOffset); } catch { Display(Config.GetResource(m_resourcemanager, "errNoScannersFound")); SetButtons(ButtonState.NoDevices); return; } // Show all the scanners, and then ask for the number of // the one to use as the new default... szText = ""; for (iScanner = 0 ;; iScanner++) { // Get the next scanner... string szScanner = jsonlookup.Get("scanners[" + iScanner + "].twidentityProductName"); if (string.IsNullOrEmpty(szScanner)) { szScanner = jsonlookup.Get("scanners[" + iScanner + "].sane"); } // We're out of stuff... if (string.IsNullOrEmpty(szScanner)) { break; } // If this is the current default, make a note of it... if (m_scanner.GetTwainLocalTy() == szScanner) { szText = (iScanner + 1) + ": " + szScanner + " ***DEFAULT***"; Display(szText); } // Otherwise, just list it... else { Display((iScanner + 1) + ": " + szScanner); } } // Finish the text for the prompt... if (string.IsNullOrEmpty(szText)) { szText = "Enter a number from 1 to " + iScanner + Environment.NewLine + "(there is no current default)" + iScanner; } else { szText = "Enter a number from 1 to " + iScanner + Environment.NewLine + szText; } // Select the default... int iNumber = 0; for (;;) { // Prompt the user... szNumber = ""; dialogresult = InputBox ( "Select Default Scanner", szText, ref szNumber ); // The user wants out... if (dialogresult != DialogResult.OK) { Display("Canceled..."); SetButtons(ButtonState.NoDevices); break; } // Check the result... if (!int.TryParse(szNumber, out iNumber)) { Display("Please enter a number in the range 1 to " + iScanner); continue; } // Check the range... if ((iNumber < 1) || (iNumber > iScanner)) { Display("Please enter a number in the range 1 to " + iScanner); continue; } // We have what we want... break; } // Tell the user what we're up to... Display(""); Display("We're going to ask the scanner some questions."); Display("This may take a minute..."); // Do a deep inquiry on the selected scanner... szScanners = m_scanner.GetAvailableScanners("getinquiry", jsonlookup.Get("scanners[" + (iNumber - 1) + "].twidentityProductName")); if (string.IsNullOrEmpty(szScanners)) { // We are unable to use the selected scanner. Please make sure your scanner is turned on and connected before trying again. Display(""); Display(Config.GetResource(m_resourcemanager, "errUnableToUseScanner")); MessageBox.Show(Config.GetResource(m_resourcemanager, "errUnableToUseScanner"), Config.GetResource(m_resourcemanager, "strFormMainTitle")); SetButtons(ButtonState.NoDevices); return; } try { jsonlookup = new JsonLookup(); jsonlookup.Load(szScanners, out lResponseCharacterOffset); } catch { Display(""); Display(Config.GetResource(m_resourcemanager, "errUnableToUseScanner")); MessageBox.Show(Config.GetResource(m_resourcemanager, "errUnableToUseScanner"), Config.GetResource(m_resourcemanager, "strFormMainTitle")); SetButtons(ButtonState.NoDevices); return; } // See if the user wants to update their note... string szNote = m_scanner.GetTwainLocalNote(); if ((iNumber >= 1) && (iNumber <= iScanner)) { // Tell the user what we're up to... Display(""); Display("We're asking what you'd like to call your scanner."); Display("Please look for a dialog box..."); // Prompt the user... dialogresult = InputBox ( "Enter Note", "Your current note is: " + m_scanner.GetTwainLocalNote() + Environment.NewLine + "Type a new note, or just press the Enter key to keep what you have.", ref szNote ); // The user wants out... if ((dialogresult != DialogResult.OK) || string.IsNullOrEmpty(szNote)) { szNote = m_scanner.GetTwainLocalNote(); } } // Register it, make a note if it works by clearing the // no devices flag. Note that the way things work now // there is only ever one scanner in the list... apicmd = new ApiCmd(); if (m_scanner.RegisterScanner(jsonlookup, 0, szNote, ref apicmd)) { m_blNoDevices = false; Display("Done..."); } else { Display("Registration failed for: " + iNumber); MessageBox.Show("Registration failed for: " + iNumber, "Error"); } // Fix the buttons... Display("Registration done..."); if (m_blNoDevices) { SetButtons(ButtonState.NoDevices); } else { SetButtons(ButtonState.WaitingForStart); } }