Wednesday, April 18, 2007

Setting <INPUT type=file> programmatically

Setting the value of an <input type="file"> tag programmatically is IMPOSSIBLE, right?

Well... Yes, it is.

There is no way to set the value property of this tag in any way known to mankind.

But...

If you use Windows, and REALLY need to automate the upload of a file through the browser, there is a way. It is hard, very difficult, and involve a great deal of knowing what you are doing.

The first step is to brush up your old Win32 API knownledge, you're going to need it.

After all, we're talking about hacking up one of the paramounts of browser security.

Second, open up your VisualStudio and create a new WindowsApplication.

Now that you have a nice and virgin WinForm in front of you, put inside a WebBrowser control.

I won't tell you how to navigate to where you want to upload the file, that's up to you.

Oh... you don't know know how to get the <input type="file"> element? Well... get back to school, and learn it.

All right, you've got your nice INPUT element, so let's proceed.

At this point your program needs to divide itself in two threads.

The main thread will call the click() function of the INPUT element, which will display the nice and lovely Open File dialog, that is so dear to us.

The secondary thread needs to enumerate all the windows on the dektop, until it gets the right Dialog, i.e. the Open File dialog that was shown by your application. Tip: EnumWindows and GetParent.

Then with the handle to the Open File dialog, find the EditBox where we're going to put the name of the file to be uploaded.

With the help of Spy++ we notice that, in Windows XP, the Open File dialog has a control of type ComboBoxEx32, which is where the user types the name of the file.

After that, we can use FindWindowEx to get the Edit portion of the ComboBoxEx32. Then using SendMessage, we set the text of the control with WM_SETTEXT.

So far so good. At this point we have the file name in the Open File dialog.

Now it gets tricky, because we need to find the Open button. I say that this is tricky because it depends on the language of the installed Windows, if it is English, we can search for the &Open in the button caption with a WM_GETTEXT message.

Finding the button we just send a BM_CLICK message, which will close the Open File dialog, setting the value of <input type="file"> tag.

Then simply exit gracefully of your secondary thread, call up the submit() function of the form, and you're all set.

I told you it is hard and difficult. But it can be done.

0 Comments:

Post a Comment