Solved

WebBrowser Control File Download

Posted on 2001-09-06
22
741 Views
Last Modified: 2008-02-01
I am trying to download a file using the WebBrowser control provided with Visual Basic.  The problem with the page is that for security reasons the downloads are triggered by submitting a hidden form, so I do not have a download location for the file.  I can simulate this and trigger the file to download, but the user still sees a prompt asking them if they want to save or open the file and a prompt asking them where they want to save it.  

Is there anyway that I can automatically save the file or at least set a default download path?

Thanks for any assistance that you can give.

bg
0
Comment
Question by:BrianG
  • 8
  • 7
  • 5
  • +1
22 Comments
 
LVL 2

Expert Comment

by:ramses
ID: 6460648
As far as I know not.  But if you now where the download comes from (ftp, http) and its location, you can add code to download it through code by using wininet.dll


Should you require more info on this, just scream and I'll provide you with some code to get you started.



Ramses
0
 

Author Comment

by:BrianG
ID: 6460691
Unfortunately the actual location of the file is an unknown.  A compiled CGI script takes care of the request and I do not have direct access to the file.

Thanks for your comment.

bg
0
 
LVL 2

Expert Comment

by:ramses
ID: 6460760
Still, you can accomplish this by using wininet.dll to handle the http requests all by yourself.

There are two things to think of

You have to open (with wininet.dll) the url with the hidden field on it and save that to a tempfile.

Then you must extract some of the file:

<FORM ACTION="someurl" METHOD="post/get"

extract someurl and post/get

<INPUT TYPE="HIDDEN" NAME="somehidden"
<INPUT TYPE="...

extract all form elements that make pairs
(a pair is a value like somehidden=somevalue)

If method is post, take the actionurl and add all the pairs to it like this actionurl?pair1name=pair1value&pair2name=pair2value...

and open that url through winint.dll

If the method is GET, let me know, because it's then a total difrent approach.

So, you open that url and then you get transfered to the file that you want to download, so save it through disk and you're finished.


Please note that I have given it in simple explanations, but it's not simple at all!


Should you want to go this way, please let me know and we'll work it out togheter.


Things to do:

Make module for wininet.dll for HTTP access
Make small parser for html files to extract what we need




Ramses
0
 

Author Comment

by:BrianG
ID: 6460882
I think that you have the post and get mixed up.  Get places the parm pairs to the url and the post is behind the scenes.

Of course I am dealing with the more complicated of the two.  The method is post and it is going behind the scenes.  I have tried adding the pairs to the URL just in case it took both, but it did not work.

I have used the wininet control before, so you don't have to go into too much detail on that.  I already have something set up to parse the page too.

I really appreciate your help on this!

bg
0
 
LVL 2

Expert Comment

by:ramses
ID: 6461019
You're right, i got them mixed-up, but that doesn't matter as long as we understand each other :-)

Please note that if you use the wininet control, it has limitations, and I don't know if it will be suitable for what were about to do.

I'll look up an article how to simulate a post submit for a form.  I've read it somewere on MSN I bellieve.


Anyway, I'll look it up and let ya know as soon as I find it


Ramses
0
 

Author Comment

by:BrianG
ID: 6461036
I can submit the form by using the document property of the WebBrowser control.  With this property you have access to all of the page elements and javascript functions.  The problem with this is that it pops up the dialog.

Or are you saying that there is a way to simulate a post with the wininet control?

bg
0
 

Author Comment

by:BrianG
ID: 6461051
These look of interest.  I need to read them further though.

For C++:

http://support.microsoft.com/support/kb/articles/Q165/2/98.ASP

For VB?:
http://support.microsoft.com/support/kb/articles/Q167/6/58.ASP
0
 
LVL 2

Expert Comment

by:ramses
ID: 6461052
It seams to be much more complicated from what I read.

The code I'm about to give is in C, so we have to get it running in VB.

What I feared of is true, we have to send a header that indicates the proper content-type.

Here's the code that I found on MSDN

The information in this article applies to:

The Microsoft Foundation Classes (MFC), included with:
Microsoft Visual C++, 32-bit Enterprise Edition, version 4.2
Microsoft Visual C++, 32-bit Professional Edition, version 4.2
Microsoft Visual C++, 32-bit Enterprise Edition, version 5.0
Microsoft Visual C++, 32-bit Professional Edition, version 5.0
Microsoft Internet Explorer (Programming) versions 4.0, 4.01

--------------------------------------------------------------------------------


SUMMARY
To properly simulate a Form submission using WinInet, you need to send a header that indicates the proper Content-Type. For Forms, the proper Content-Type header is:

Content-Type: application/x-www-form-urlencoded



MORE INFORMATION
In many cases, the server does not respond appropriately if a Content-Type is not specified. For example, the Active Server Pages component of IIS 3.0 actually checks this header specifically for 'application/x-www-form- urlencoded' before adding form variables to the "Request.Form" object. This MIME/Content-Type indicates that the data of the request is a list of URL- encoded form variables. URL-encoding means that space character (ASCII 32) is encoded as '+', special character such '!' encoded in hexadecemal form as '%21'.

Here is a snippet of code that uses the MFC WinInet classes to simulate a Form POST request:

   CString strHeaders =
      _T("Content-Type: application/x-www-form-urlencoded");
   // URL-encoded form variables -
   // name = "John Doe", userid = "hithere", other = "P&Q"
   CString strFormData = _T("name=John+Doe&userid=hithere&other=P%26Q");

   CInternetSession session;
   CHttpConnection* pConnection =
      session.GetHttpConnection(_T("ServerNameHere"));
   CHttpFile* pFile =
      pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST,
                              _T("FormActionHere"));
   BOOL result = pFile->SendRequest(strHeaders,
      (LPVOID)(LPCTSTR)strFormData, strFormData.GetLength());
Without MFC, the same code translates to straight SDK calls as follows:
   static TCHAR hdrs[] =
      _T("Content-Type: application/x-www-form-urlencoded");
   static TCHAR frmdata[] =
      _T("name=John+Doe&userid=hithere&other=P%26Q");
   statuc TCHAR accept[] =
      _T("Accept: */*");

   // for clarity, error-checking has been removed
   HINTERNET hSession = InternetOpen("MyAgent",
      INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
   HINTERNET hConnect = InternetConnect(hSession, _T("ServerNameHere"),
      INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
   HINTERNET hRequest = HttpOpenRequest(hConnect, "POST",
      _T("FormActionHere"), NULL, NULL, accept, 0, 1);
   HttpSendRequest(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata));
   // close any valid internet-handles


Much to do huh?
0
 
LVL 2

Expert Comment

by:ramses
ID: 6461067
It looks like you answered you're own question.  It includes a VB example too...  by using the webbrowser object itself.

I would definitly give that article a go

http://support.microsoft.com/support/kb/articles/Q167/6/58.ASP

it has an example, and what do ya have to lose?


Ramses  



Let me know...
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6461573
Interesting...
0
 

Author Comment

by:BrianG
ID: 6461738
Ramses,

I don't have any more time to look at this today, but I really appreciate your help and I will let you know tomorrow how it turns out.

I plan on giving you full credit fo rthis, but I want to leave it out here for a while to let people take a gander and offer their opinion.

bg
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

Author Comment

by:BrianG
ID: 6488387
Neither of these articles says anything about saving a file that is triggered to be downloaded via posting a form.

Any other thoughts?

bg
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6499818
Please, could you post site link? I could do a try.
0
 

Author Comment

by:BrianG
ID: 6499849
Unfortunately I cannot give the link.  It is a secured site and I can't give you the log in and password.

What is happening is similar to many site on the web when you click a link to download a file. You click on a link and you are taken to a page where they say your download will begin shortly.  The download starts and you are prompted for the location to save the file and what not.  This is like on download.com or tucows.com.

ie. WinAmp from download.com

http://download.cnet.com/downloads/0,10152,0-1896413-110-6209056,00.html?gid=26164&tag=st.dl.1896413-100-6209056.ur.1896413-110-6209056

Think of it like this, but you have to submit a form.  I don't know if I can find a site that mimicks exactly what I am doing.

Thanks for your help.

Brian
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6499984
Don't give me log and password. For test that i want to do i don't need them at all.
Just need to see how it is implemented with maximun details, if possible.
Cheers
0
 

Author Comment

by:BrianG
ID: 6500236
Well the file download area is beyond the log in, so you would not even be able to see it without logging into the site.

bg
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6500399
oops!, well, then...
We could work with webbrowser object model to achieve this task, but, at least, i need to see html code from those pages.
Cheers
0
 
LVL 1

Expert Comment

by:Moondancer
ID: 6843001
Question(s) below appears to have been abandoned. Your options are:
 
1. Accept a Comment As Answer (use the button next to the Expert's name).
2. Close the question if the information was not useful to you. You must tell the participants why you wish to do this, and allow for Expert response.
3. Ask Community Support to help split points between participating experts, or just comment here with details and we'll respond with the process.
4. Delete the question. Again, please comment to advise the other participants why you wish to do this.

For special handling needs, please post a zero point question in the link below and include the question QID/link(s) that it regards.
http://www.experts-exchange.com/jsp/qList.jsp?ta=commspt
 
Please click the Help Desk link on the left for Member Guidelines, Member Agreement and the Question/Answer process.  Click you Member Profile to view your question history and keep them all current with updates as the collaboration effort continues, in the event new items have been created since this listing was pulled.

http://www.experts-exchange.com/jsp/cmtyHelpDesk.jsp

To view your open questions, please click the following link(s) and keep them all current with updates.
http://www.experts-exchange.com/questions/Q.20102124.html
http://www.experts-exchange.com/questions/Q.20179398.html


PLEASE DO NOT AWARD THE POINTS TO ME.  
 
------------>  EXPERTS:  Please leave any comments regarding this question here on closing recommendations if this item remains inactive another three days.
 
Thank you everyone.
 
Moondancer
Moderator @ Experts Exchange

P.S.  For any year 2000 questions, special attention is needed to ensure the first correct response is awarded, since they are not in the comment date order, but rather in Member ID order.
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6844077
If there is not a solution already found by Brian himself...
I am in a box since i can't see how target site works.
As always, excellent job Moon...!
Cheers
0
 
LVL 16

Accepted Solution

by:
Richie_Simonetti earned 300 total points
ID: 6844089
maybe we can catch url in beforenavigate2 or FileDownload or DownloadBegin events.
If so, maybe cancelling the operation and do it ourselves.
It is an idea (From Ark's code):
Private Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" (ByVal pCaller As

Long, ByVal szURL As String, ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long)

As Long

Public Function SaveURL(ByVal sUrl As String, ByVal sFileName As String) As Boolean
 SaveURL = URLDownloadToFile(0&, sUrl, sFile, 0, 0)
End Function

'=====Using========
If SaveURL("http://www.somewhere.com/file.txt", "c:\folder\temp.txt") Then MsgBox "Download complete!"
0
 
LVL 1

Expert Comment

by:Moondancer
ID: 6850753
BrianG logged in 3/6, after this request was posted and chose not to respond.  I have therefore finalized this.  In the event BrianG returns with additional needs related to this question, please respond.
Thanks,
Moondancer - EE Moderator
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
ID: 6850914
OK.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now