0

I can send a text from my C# WinForm app to another application like Notepad using:

SendKeys.SendWait("Hello");

but I need to send text to an html input element in Firefox. There are several ways to select a target application. This SO Question uses code like:

Process p = Process.GetProcessesByName("notepad").FirstOrDefault();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);

to set the desired app to the foreground so it will receive the text. But this does not work with the app named "firefox", probably because it uses not 1 but 4 processes according to the Task Manager.

I tried another approach: right before calling SendKeys.SendWait, just switch back to the last active application just like Alt-Tab does, using code from this SO Question, which works for Notepad, and for the Chrome browser, but not for Firefox.

The purpose of this is to get data from a weight measurement device (scale), connected to the RS232 port, to the html input element in the browser. The same principle of simulating a keyboard is routinely used with USB barcode scanners.

Any idea how to do this with Firefox?

Am I perhaps on the wrong track, and are there perhaps much different methods to get text in the keyboard?

Roland
  • 4,619
  • 7
  • 49
  • 81
  • XY Problem here? I think you are going the wrong way all along. What you want to do is send your measurements to a server. You try to do it via pasting text to a third party client application. Why not trigger the receiving side directly? If I would develop a brwoser, I would prevent any other application to put data into any textfields. Smells like something bad. possibly a safety measure!? – Romano Zumbé Jun 20 '17 at 10:44
  • XY Problem indeed. I'd venture that the correct way to do this would be to create a local HTTP server on a known port in your data-gathering app, to set up correct CORS on it, then get the webpage to connect to the local app on (`http://localhost:[knownPort]`) and get the data. You could get even fancier with a websocket, but this might not work on older versions of windows. Signalr, WebApi and OWIN self-host might be appropriate. – spender Jun 20 '17 at 10:54
  • @RomanoZumbé OK most web apps work only with devices like keyboard and touchpad, but for industrial applications we have LOTS of other devices, like barcode scanners, scales, etc. Barcode scanners usually come with keyboard drivers, but data from scales is more complicated and need preprocessing, so I need to write my own keyboard driver here. Nothing special from the conceptual point of view, but now my problem is how to make that driver... – Roland Jun 20 '17 at 10:56
  • What is an XY problem anyway? Can't we just focus on the problem at hand? Why can I send keyboard data to Notepad and Chrome, and not to Firefox? And the driver of the barcode scanner can. Please... – Roland Jun 20 '17 at 10:58
  • @Roland What happens with the data, once it is in the HTML input field? – Romano Zumbé Jun 20 '17 at 10:58
  • @RomanoZumbé Then the web app combines this with other weight measurements, there are choices for different types of soil samples to be weighted, lots of workflow, etc etc. Eventually everything goes to the server and is stored in a database. – Roland Jun 20 '17 at 10:59
  • An XY problem is when a person asks a question about a specific path with which they would like to attack a problem, when the real answer to the *actual problem* they are trying to solve lies down a different path. Obviously it's just an opinion. However, I would very much recommend the local HTTP server approach. Spotify use this technique very successfully. And it will work next year, and the year after that. Sending keys. It's kind-of hit'n'miss, as you've discovered, no? – spender Jun 20 '17 at 11:01
  • @Roland And the combination can't be done either in a standard app or on the server? Is the web app working locally (e.g. via JavaScript)? – Romano Zumbé Jun 20 '17 at 11:01
  • @spender XY ok if we find another SIMPLE solution. But this kind of workflow apps are very suitable for web app. With the barcode scanner this works really great, no kind-of hit'n miss, just working perfect. This is going to work great with Chrome, but as am a loyal user of Firefox, I'd like to get it to work on Firefox too. – Roland Jun 20 '17 at 11:05
  • @Roland My worry for this key-based approach is that browser implementations change all the time. There is no standard regarding how a browser might have keys injected into it, and this means it could be **subject to change without notice**. You might find that the new "4 process" Firefox (only the most recent version) behaves very differently to the previous version. On the other hand, HTTP communication, and the language tools in the browser are very precisely specified and unlikely to stop working. even in 10 years time. I know which one I would choose for a hassle free maintenance contract – spender Jun 20 '17 at 11:09
  • @spender I would guess that the barcode scanner keyboard driver is not especially designed for firefox, but firefox sees this device as a keyboard. That scanner is going to work with firefox until the end of times for sure. – Roland Jun 20 '17 at 11:12

1 Answers1

0

Can't you use WinForms WebBrowser? Also consider using Selenium WebDriver which is available via Nuget. I think it does exactly what you need.

That's an example from docs:

using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

// Requires reference to WebDriver.Support.dll
using OpenQA.Selenium.Support.UI;

class GoogleSuggest
{
    static void Main(string[] args)
    {
        // Create a new instance of the Firefox driver.
        // Note that it is wrapped in a using clause so that the browser is closed 
        // and the webdriver is disposed (even in the face of exceptions).

        // Also note that the remainder of the code relies on the interface, 
        // not the implementation.

        // Further note that other drivers (InternetExplorerDriver,
        // ChromeDriver, etc.) will require further configuration 
        // before this example will work. See the wiki pages for the
        // individual drivers at http://code.google.com/p/selenium/wiki
        // for further information.
        using (IWebDriver driver = new FirefoxDriver())
        {
            //Notice navigation is slightly different than the Java version
            //This is because 'get' is a keyword in C#
            driver.Navigate().GoToUrl("http://www.google.com/");

            // Find the text input element by its name
            IWebElement query = driver.FindElement(By.Name("q"));

            // Enter something to search for
            query.SendKeys("Cheese");

            // Now submit the form. WebDriver will find the form for us from the element
            query.Submit();

            // Google's search is rendered dynamically with JavaScript.
            // Wait for the page to load, timeout after 10 seconds
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
            wait.Until(d => d.Title.StartsWith("cheese", StringComparison.OrdinalIgnoreCase));

            // Should see: "Cheese - Google Search" (for an English locale)
            Console.WriteLine("Page title is: " + driver.Title);
        }
    }
}
Eloncase
  • 1
  • 2
  • Thanks for this original solution. But am I correct that this would mean to trade Firefox for a Winforms browser? And lose the platform independence? OK the winforms scale app is windows, but still. Then I would rather use Chrome instead. – Roland Jun 20 '17 at 11:07
  • No, Selenuim will "connect" to any browser. You don't need to use WinForms WebBrowser at all that way. – Eloncase Jun 20 '17 at 11:11
  • ...but will selenium continue working with new browser versions, or will OP need to rebuild against new versions of selenium when things break? Using what is essential a debugging/testing tool in a desktop app seems dangerous – spender Jun 20 '17 at 11:12
  • I will definitely look into this. Just have to leave from work in 15 minutes. – Roland Jun 20 '17 at 11:15
  • @spender it will continue to work unless browser update will do something major. So even if something will break it will not be that often – Eloncase Jun 20 '17 at 11:23
  • @spender ... job security ... :-) – Roland Jun 20 '17 at 11:25