能不能在下载之前截获准备要下载的文件?好像用BHO只能截获一个连接,但不知道是不是可以下载的文件。怎样才能知道?或者能否预先分析要下载的内容?

解决方案 »

  1.   

    截获链接后,分析其名称,比如后缀满足"*.zip,*.rar,*.exe,*.jpg....."等则视为可下载的,
    大部分下载软件也是这样的.
      

  2.   

    可惜了,现在很多链接是没有明显的后缀的,不信你们仔细观察看看。很多都是用GET METHOD来做的,比如http://www.site.com/link?fileid=245667775,从连接上根本看不出来是个可以下载的文件。可是浏览器怎么能够判断是个文件,连文件名都知道呢?
      

  3.   

     回复人:SnHnBn(大可达) ( 二级(初级)) 信誉:100  2006-10-7 12:16:27  得分:0
    ?  可惜了,现在很多链接是没有明显的后缀的,不信你们仔细观察看看。很多都是用GET METHOD来做的,比如http://www.site.com/link?fileid=245667775,从连接上根本看不出来是个可以下载的文件。可是浏览器怎么能够判断是个文件,连文件名都知道呢?=========================================================
    没关系,只要截获链接,然后打开这个链接,接着用HttpQueryInfo查询一下内容类型, 记着传参数HTTP_QUERY_CONTENT_TYPE, 通常htm,html格式返回text/html
      

  4.   

    http://www.site.com/link?fileid=245667775
    这样的链接都是重定向的链接,向这个链接GET一下,就会得到下载文件的具体地址。
      

  5.   

    akirya 你说得很对,可是这样又有新问题:怎样向这个链接GET一下?单独开个Socket?或是怎样能从IE上获取得到Get之后的重定向?
      

  6.   

    yjgx007 你指的是使用独立的WinInet来操作这个连接吧?会不会有些网站防盗链机制会起作用而导致无法HttpQueryInfo啊?不过倒是感觉接近目标了。
      

  7.   

    It depends
    If you start another HTTP web request in a webbrowser application, you may need to login   again.
      

  8.   

    参考:
    http://blog.csdn.net/lion_wing/articles/534716.aspx
    http://blog.csdn.net/lion_wing/archive/2006/06/27/839134.aspx
      

  9.   

    To jiangsheng(蒋晟.Net[MVP]) :
    login again说得倒是挺容易的,不知道如何才能用程序自动做到?
      

  10.   

    To lion_wing(凤之焚):
    似乎你说的这个正是我需要的,我先去试试,然后回来结贴。
      

  11.   

    private void webBrowser1_StartNavigate(object sender, BrowserExtendedNavigatingEventArgs e)
            {
                if (e.Url.LocalPath.Contains("exportDoc.asp"))
                {
                    e.Cancel = true;
                    string[] QueryParameters = e.Url.Query.Split("&".ToCharArray());
                    string FileName = QueryParameters[0];
                    //remove "?filename="
                    FileName = FileName.Substring(
                        FileName.IndexOf('=')+1);
                    FileName = Microsoft.JScript.GlobalObject.unescape(FileName);
                    string LocalFile =
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "InfraHealth");
                    Directory.CreateDirectory(LocalFile);
                    LocalFile = Path.Combine(LocalFile, FileName);
                    DownloadFile(e.Url, LocalFile);
                }
                Debug.WriteLine(
                string.Format("Navigating to :{0}",e.Url));
            }void DownloadFile(Uri DownloadURL, string LocalFile)
            {
                try
                {
                    string UserAgent = "CSharp HTTP Sample";
                    string GetMethod = "GET";
                    string PostMethod= "POST";
                    Uri LoginURL= new Uri("https://www.example.com/checklogon.asp");
                    string PostData = "username=Example&password=example";                CookieContainer CookieJar = new CookieContainer();
                    ServicePointManager.ServerCertificateValidationCallback += 
                        new RemoteCertificateValidationCallback(myCertificateValidation);
                    
                    HttpWebRequest LoginRequest=null;
                    CreateHttpWebRequest(ref LoginRequest, LoginURL,ref CookieJar, UserAgent, PostMethod, PostData);
                    HttpWebResponse LoginResponse = (HttpWebResponse)LoginRequest.GetResponse();
                    DebugWriteContent(ref LoginResponse);
                    CookieCollection cookies = LoginResponse.Cookies;
                    LoginResponse.Close();
                    HttpWebRequest DownloadRequest = null;
                    CreateHttpWebRequest(ref DownloadRequest, DownloadURL, ref CookieJar, UserAgent, GetMethod, string.Empty);
                    HttpWebResponse DownloadResponse = (HttpWebResponse)DownloadRequest.GetResponse();
                    Stream DownloadStream = DownloadResponse.GetResponseStream();
                    
                    string TempFile=Path.GetTempFileName();
                    int buffSize = 4 * 1024; //4KB
                    byte[] buffer = new byte[buffSize];
                    using (FileStream fileStream = File.OpenWrite(TempFile))
                    {
                        while (true)
                        {
                            int count = DownloadStream.Read(buffer, 0, buffSize);
                            if (count == 0) break;
                            fileStream.Write(buffer, 0, count);
                        }
                    }
                    DownloadStream.Close();
                    DownloadResponse.Close();
                    File.Copy(TempFile, LocalFile, true);
                }
    void CreateHttpWebRequest(ref HttpWebRequest webRequest, Uri URL, ref CookieContainer cookie,
                string UserAgent, string Method, string PostDataText)
            {
                webRequest
                    = (HttpWebRequest)WebRequest.Create(URL);
                // set the HttpWebRequest objects cookie container
                // if you have any cookies that you want to go with the request you can add them 
                // to the cookiecontainer. If you had made a previous request that returned any cookies
                // that needed to be sent on subsequent request this will make sure that they are sent. 
                webRequest.CookieContainer = cookie;
                // the default credentials are usually the Windows credentials (user name, password, and domain) of the user running the application
                webRequest.Credentials = CredentialCache.DefaultCredentials;
                webRequest.UserAgent = UserAgent;
                webRequest.KeepAlive = true;
                webRequest.Headers.Set("Pragma", "no-cache");
                //set the request timeout to 5 min.
                webRequest.Timeout = 300000;
                webRequest.Method = Method;
                // See what the Method is a POST 
                if ("POST" == Method)
                {
                    // add the content type so we can handle form data
                    webRequest.ContentType = "application/x-www-form-urlencoded";
                    if (PostDataText.Length < 1) // we don't have any data to post
                    {
                        return;
                    }
                    // we need to store the data into a byte array
                    byte[] PostData = System.Text.Encoding.ASCII.GetBytes(PostDataText);
                    webRequest.ContentLength = PostData.Length;
                    Stream tempStream = webRequest.GetRequestStream();
                    // write the data to be posted to the Request Stream
                    tempStream.Write(PostData, 0, PostData.Length);
                    tempStream.Close();
                }
                return;
            }
      

  12.   

    To jiangsheng(蒋晟.Net[MVP]) :
    Uri LoginURL= new Uri("https://www.example.com/checklogon.asp");
    string PostData = "username=Example&password=example";
    似乎必须针对特定的网页内容来作处理,不具备通用性。
    To lion_wing(凤之焚):
    有没有全能的MIME Type?不知怎么拦截不到下载文件,连MIME Filter的DLL都没有加载。
      

  13.   

    To  lion_wing(凤之焚): 
    好像对下载的文件不起作用,只能处理要显示的内容?
      

  14.   

    To lion_wing(凤之焚): 
    谢谢,问题搞定了。不过每种要下载的文件要对应一个mime type,似乎通用性还不够,不知道能不能直接截获未注册mime type的文件?
      

  15.   

    http://windowssdk.msdn.microsoft.com/en-us/library/ms673378(VS.80).aspx
      

  16.   

    得到要的下载文件要用RegisterNamespace
    得到显示的内容要用RegisterMimeFilter更多的MimeType可以查看MSDN!
      

  17.   

    To jiangsheng(蒋晟.Net[MVP]):
    可惜目标平台不允许我用IDownloadManagerTo lion_wing(凤之焚):
    我想知道的是可不可以不指定MimeType?就是说不针对特定MimeType的通用Filter?
      

  18.   

    如果可以有通用Filter的话,另外给分,谢谢。