1

I'm using Geckofx in my winform application to fill a form on a website. One of the controls is a button "Choose Files" which lets you select and upload a local file. I want to automate this process by doing this fully via code.

I managed to click this button via code:

Gecko.DOM.GeckoButtonElement button = new Gecko.DOM.GeckoButtonElement(doc.GetElementsByClassName("choose_files_btn").First().DomObject);
button.Click();

As a result a file dialog is opened automatically but I want to automate the file choosing part and clicking 'OK' as well. I tried inspecting the webpage to find whether I could assign the path of my local file to some Gecko element but couldn't find anything of this sort.

I also thought about handling the event of opening the file dialog but couldn't find any event handler in Gecko. I found Gecko.LauncherDialog.Download event handler which is used for handling downloading a file using Geckofx browser. But there's no such event handler for uploading files using Geckofx browser, if there is and I missed it, do tell.

Maybe I can use an event handler not from Gecko but from System, if I write an event handler which will catch every open file dialog event but I don't know whether that's even possible.

musicinmusic
  • 247
  • 1
  • 11

1 Answers1

0

Here is a solution, to upload without showing the file upload dialog:

GeckoHtmlElement el = webbrowser.DomDocument.GetElementsByTagName("input").FirstOrDefault(elz => elz.GetAttribute("type") == "file"); //inpout type file element
var fileNames = new IntPtr[1];
fileNames[0] = new Gecko.CustomMarshalers.WStringMarshaler().MarshalManagedToNative(file); //file = path to file you want to upload


var domInput = Xpcom.QueryInterface<nsIDOMHTMLInputElement>(el.DOMHtmlElement);
domInput.MozSetFileNameArray(fileNames, (uint)fileNames.Length);

Marshal.ReleaseComObject(domInput);

DomEventArgs ev = webbrowser.Document.CreateEvent("HTMLEvents");
var webEvent = new Event(webbrowser.Window.DomWindow, ev.DomEvent as nsISupports);
webEvent.InitEvent("change", true, true);
el.GetEventTarget().DispatchEvent(ev);

new Gecko.CustomMarshalers.WStringMarshaler().CleanUpNativeData(fileNames[0]); //delete everything
BlasterGod
  • 196
  • 1
  • 13
  • Thank you so much! I just tested it and it works as expected. – musicinmusic May 19 '19 at 21:43
  • I don't think this is a viable solution anymore. Mozilla's description of [MozSetFileNameArray()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/mozSetFileNameArray) makes it look like it's not something to rely on. And based on [this question](https://stackoverflow.com/questions/56007594/programatically-upload-file-using-geckofx60-worked-in-29-not-in-60) I suspect support has been dropped by GeckoFx60. Sadly I don't have any suggestions though. @BlasterGod can you maybe include some of the library versions you got this to work with? – Anarki Dec 03 '19 at 21:39
  • Anarki, this works in all versions but 60 upwards unfortunately. I would like to see a solution for version 60 and up – BlasterGod Dec 11 '19 at 17:17
  • This does not work on v 60. Is there any other solution, please? – Taki Elias Jul 09 '21 at 14:07
  • @Anarki i have found the Solution for GeckoFx60 on [this answer](https://stackoverflow.com/a/24755325/5561276) – Zahid Zuhair Oct 01 '21 at 12:10