1

Тема: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Как такое замутить без использования сторонних приблуд при условии, что в ссылке на файл расширение не указано.

2

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Э... Лично я ничего не понял.

3

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Я это понял так. Есть ссылка на скачивание типа http://avatars-fast.yandex.net/get-dire … dkojGA/y90. То есть в ссылке не указано расширение файла (в данном случае .JFIF).
Согласно заданию, скрипт получет ссылку, скачивает файл, самостоятельно определяет расширение и присваивает файлу имя.

4

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Именно это я и имел в виду.

5

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Для конкретного случая:


url = http://avatars-fast.yandex.net/get-direct/R85qdm4hRHr-gA65dkojGA/y90

Type := Request(url).getResponseHeader("Content-Type")
msgbox %  "Ext: " SubStr(Type, InStr( Type, "/")+1)

Request(url) {  
    WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
    WebRequest.Option(6) := False ; No redirects
    WebRequest.Open("GET", url, false)
    WebRequest.Send()
    Return, WebRequest 
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

6

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

А для общего случая?
На оф.форуме SKAN писал, что:

we may find the filename with a few DllCall()s and then use it with URLDownloadToFile

Но дальше тема заглохла.

7 (изменено: Malcev, 2014-05-15 07:28:54)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

На оф.форуме ответили.
И объединив их вариант с вариантом serzh82saratov получилось так:

Download("https://docs.google.com/uc?export=download&id=0B7FildjsrNkILWhYVHYwanJLS3c")
Download("http://avatars-fast.yandex.net/get-direct/R85qdm4hRHr-gA65dkojGA/y90")

Download(url) {
   If (!InStr(url,"://"))
       url := "http://" . url
   WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   ComObjError(false)
   WebRequest.Open("GET", url)
   WebRequest.Send()
   cdHeader := WebRequest.GetResponseHeader("Content-Disposition")
   If (cdHeader)
   {
      RegexMatch(cdHeader, "filename=""([^""]+)""", match)
      fileName := match1
   }
   Else
   {
      SplitPath, url, fileName, , ext
      if (ext = "")
      {
         ext := WebRequest.GetResponseHeader("Content-Type")
         if (ext != "")
            filename := filename "." SubStr(ext, InStr(ext, "/")+1)
      }
   }
   UrlDownloadToFile, %url%, %fileName%
}

8 (изменено: serzh82saratov, 2014-05-15 11:34:34)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Нехорошо это, получается файл 2 раза скачивается
http://www.autohotkey.com/board/topic/7 … ntry475484


Download("http://avatars-fast.yandex.net/get-direct/R85qdm4hRHr-gA65dkojGA/y90")
Download("https://docs.google.com/uc?export=download&id=0B7FildjsrNkILWhYVHYwanJLS3c")
 
Download(url) {
    If (!InStr(url,"://"))
        url := "http://" . url
    WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
    ComObjError(false), WebRequest.Open("GET", url), WebRequest.Send() 
    If (cdHeader := WebRequest.GetResponseHeader("Content-Disposition")) 
        RegexMatch(cdHeader, "filename=""(?<name>[^""]+)""", file)   
    Else
    {
        SplitPath, url, fileName, , ext 
        if (ext = "" && ctHeader := WebRequest.GetResponseHeader("Content-Type"))
            filename := filename "." SubStr(ctHeader, InStr(ctHeader, "/")+1)  
    } 
    If StreamToFile(WebRequest.ResponseStream, fileName), WebRequest := ""
        MsgBox, %url%`n`n%fileName% 
    Else
        MsgBox Error! File not download in url:`n%url%
}
 
StreamToFile(Stream, fileName)   { 
    If (ComObjType(Stream) != 0xD)  
        Return 0
    pIStream := ComObjQuery(Stream, "{0000000c-0000-0000-C000-000000000046}") 
    oFile := FileOpen(fileName, "w")
    While (cbRead != 0)   
        VarSetCapacity(Buffer, 8192)
        , DllCall(NumGet(NumGet(pIStream + 0) + 3 * A_PtrSize)
        , "ptr", pIStream, "ptr", &Buffer, "uint", 8192, "ptr*", cbRead)
        , oFile.RawWrite(&Buffer, cbRead) 
    Return 1, ObjRelease(pIStream), oFile.Close()      
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

9 (изменено: Malcev, 2014-05-15 14:22:00)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Только большие файлы качать не хочет.
Например:

Download("http://dl.firedrive.com/?key=MjBBN0M5OURGMTM2MzRFODoxNDA1MzkxNjY5OmQ2ZDE5MTc4NzFjMzhmNGNjMWY3ZTg4YjA4MjkyZDQ2NTM4ZDJjY2I=")

10

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

#MaxMem 4095 

С этим тоже?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

11 (изменено: Malcev, 2014-05-15 16:17:18)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Да, с этим тоже.
Может быть как-то надо разбивать на части?
http://stackoverflow.com/questions/1844 … g-vbscript
И непонятно, как в вашем варианте сохранять файл не в A_ScryptDir.
Разобрался, как поменять директорию, осталась проблема с большими файлами:

global dir := "C:\2"
Download("http://avatars-fast.yandex.net/get-direct/R85qdm4hRHr-gA65dkojGA/y90")
Download("https://docs.google.com/uc?export=download&id=0B7FildjsrNkILWhYVHYwanJLS3c")
 
Download(url) {
    If (!InStr(url,"://"))
        url := "http://" . url
    WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
    ComObjError(false), WebRequest.Open("GET", url), WebRequest.Send() 
    If (cdHeader := WebRequest.GetResponseHeader("Content-Disposition")) 
        RegexMatch(cdHeader, "filename=""(?<name>[^""]+)""", file)   
    Else
    {
        SplitPath, url, fileName, , ext 
        if (ext = "" && ctHeader := WebRequest.GetResponseHeader("Content-Type"))
            filename := filename "." SubStr(ctHeader, InStr(ctHeader, "/")+1)  
    } 
    StreamToFile(WebRequest.ResponseStream, fileName), WebRequest := ""
}
 
StreamToFile(Stream, fileName)   { 
    If (ComObjType(Stream) != 0xD)  
        Return 0
    pIStream := ComObjQuery(Stream, "{0000000c-0000-0000-C000-000000000046}") 
    oFile := FileOpen(dir "\" fileName, "w")
    While (cbRead != 0)   
        VarSetCapacity(Buffer, 8192)
        , DllCall(NumGet(NumGet(pIStream + 0) + 3 * A_PtrSize)
        , "ptr", pIStream, "ptr", &Buffer, "uint", 8192, "ptr*", cbRead)
        , oFile.RawWrite(&Buffer, cbRead) 
    Return 1, ObjRelease(pIStream), oFile.Close()      
}

12

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Только большие файлы качать не хочет.
Например:

Так ссылка http://dl.firedrive.com/?key=MjBBN0M5OU … M4ZDJjY2I= невалидная. У меня инет мобильный, но запустив http://ru.download.nvidia.com/Windows/3 … l-whql.exe - 264 мб, ушло в ожидание, то есть как будто начало качать.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

13 (изменено: Malcev, 2014-05-15 18:42:50)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Значит у вас свободной оперативки больше, чем 264 мб.
Попробуйте с этим файлом:

Download("http://www.malcev.lv/DOM/hochu_domoj_18_05_2014.avi")

14

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

На оф.форуме предложили более правильный вариант с определением mimeType.
Вместо этого:

if (ext = "" && ctHeader := WebRequest.GetResponseHeader("Content-Type"))
   filename := filename "." SubStr(ctHeader, InStr(ctHeader, "/")+1)  

Это:

if (ext = "" && ctHeader := WebRequest.GetResponseHeader("Content-Type"))
{
   RegRead, ext, HKEY_CLASSES_ROOT, MIME\Database\Content Type\%ctHeader%, Extension
   filename := filename ext
}

15 (изменено: serzh82saratov, 2014-05-16 00:20:27)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Инфо можно получить до закачки, HttpQueryInfo(dLocation, 22)  аналог WebRequest.getAllResponseHeaders(). Как разобрать Info понятно. Метод присвоения имён можно оставить прежний, я не стал парится. Можно сделать мульти закачку - UrlDownloadToFile качает в другом процессе обновляя сообщениями Progress основного.
На этой ссылке

url = http://docs.google.com/uc?export=download&id=0B7FildjsrNkILWhYVHYwanJLS3c

скрипт вылетает почему то, остальные работают.


#SingleInstance Force
#MaxThreads 3
SetWorkingDir %A_Desktop%\

  ;  http://www.autohotkey.com/board/topic/103382-need-some-help-with-a-download-progress-bar/
 
url = http://www.malcev.lv/DOM/hochu_domoj_18_05_2014.avi

Download(url)

Download(dLocation_p)
{
    global path, dLocation, FullFileName, FullSize 
    dLocation = %dLocation_p% 
    SplitPath, dLocation, path
    FullSize := HttpQueryInfo(dLocation, 5) 
    MsgBox, , % path, % Info := HttpQueryInfo(dLocation, 22)
    Progress, H80, , Downloading..., %path% Download
    SetTimer, GetSize, 100
    UrlDownloadToFile, %dLocation%, %path% 
    SetTimer, GetSize, -1
    Return
}

GetSize:
    FileOpen(path, "r")
    FileGetSize, FSize, %path%
    UpdateSize := Ceil((FSize / FullSize) * 100)   
    Progress, %UpdateSize%, %UpdateSize%`% Complete, Downloading... 
        , % Trim(t:=FSize/1000, "0") "kb / " RTrim(t:=FullSize/1000, "0") "kb || " path
Return
 
HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="") {
    hModule := DllCall("LoadLibrary", "str", dll := "wininet.dll") 
    ver := ( A_IsUnicode && !RegExMatch( A_AhkVersion, "\d+\.\d+\.4" ) ? "W" : "A" )
    InternetOpen := dll "\InternetOpen" ver
    HttpQueryInfo := dll "\HttpQueryInfo" ver
    InternetOpenUrl := dll "\InternetOpenUrl" ver 
    If (Proxy != "")
        AccessType=3
    Else
        AccessType=1 
    io_hInternet := DllCall( InternetOpen
        , "str", ""
        , "uint", AccessType
        , "str", Proxy
        , "str", ProxyBypass
        , "uint", 0) ;dwFlags
    If (ErrorLevel != 0 or io_hInternet = 0)
    {
        DllCall("FreeLibrary", "uint", hModule)
        return, -1
    } 
    iou_hInternet := DllCall( InternetOpenUrl
        , "uint", io_hInternet
        , "str", url
        , "str", ""
        , "uint", 0
        , "uint", 0x80000000
        , "uint", 0)
    If (ErrorLevel != 0 or iou_hInternet = 0)
    {
        DllCall("FreeLibrary", "uint", hModule)
        return, -1
    } 
    VarSetCapacity(buffer, 1024, 0)
    VarSetCapacity(buffer_len, 4, 0) 
    Loop, 5
    {
        hqi := DllCall( HttpQueryInfo
            , "uint", iou_hInternet
            , "uint", QueryInfoFlag
            , "uint", &buffer
            , "uint", &buffer_len
            , "uint", 0)
        If (hqi = 1) {
            hqi=success
            break
        }
    } 
    IfNotEqual, hqi, success, SetEnv, res, timeout 
    If (hqi = "success")
    {
        p := &buffer
        Loop
        {
            l := DllCall("lstrlen", "UInt", p)
            VarSetCapacity(tmp_var, l+1, 0)
            DllCall("lstrcpy", "Str", tmp_var, "UInt", p)
            p += l + 1
            res := res . tmp_var
            If (*p = 0)
                Break
        }
    } 
    DllCall("wininet\InternetCloseHandle",  "uint", iou_hInternet)
    DllCall("wininet\InternetCloseHandle",  "uint", io_hInternet)
    DllCall("FreeLibrary", "uint", hModule) 
    return, res
}
 
 
 
Esc::   
    ExitApp
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

16 (изменено: Malcev, 2014-05-16 00:33:20)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Ну и в итоге у вас получился скрипт, который скачивает все, кроме файлов со скрытым расширением.
Проверял не только на гугле.
И еще я заметил, что UrlDownloadToFile качает медленнее чем WinHttpRequest.

17

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Ну и в итоге у вас получился скрипт, который скачивает все, кроме файлов со скрытым расширением.

Это ведь качает - http://avatars-fast.yandex.net/get-dire … dkojGA/y90

Метод присвоения имён можно оставить прежний, я не стал парится.

Неужели не очевидно?

И еще я заметил, что UrlDownloadToFile качает медленнее чем WinHttpRequest.

Главное\потому, что не в оперативку.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

18

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

По той ссылке с гугла в этом цикле происходит ошибка, хотя первые 63 символа инфо определяются, тут надо посвящённым смотреть.


        p := &buffer
        Loop
        {
            l := DllCall("lstrlen", "UInt", p)
            VarSetCapacity(tmp_var, l+1, 0)
            DllCall("lstrcpy", "Str", tmp_var, "UInt", p)
            p += l + 1
            res := res . tmp_var
            If (*p = 0)
                Break
        }
    } 
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

19

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Для начала в AHK_L у поинтеров, как и у хэндлов, тип данных не "UInt", а "Ptr".

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

20

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.


            l := DllCall("lstrlen", "Ptr", p)  
            VarSetCapacity(tmp_var, l+1, 0)
            DllCall("lstrcpy", "Str", tmp_var, "Ptr", p)


url = https://docs.google.com/uc?export=download&id=0B7FildjsrNkILWhYVHYwanJLS3c

С этой ссылкой по прежнему вылетает.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

21

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Ну, вот так правильно:

HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="")
{
   hModule := DllCall("LoadLibrary", "str", "wininet.dll", Ptr)
   AccessType := Proxy = "" ? 1 : 3
   
   Loop 1
   {
      Error := 1
      if !io_hInternet := DllCall("wininet\InternetOpen", "str", "", "uint", AccessType, "str", Proxy, "str", ProxyBypass, "uint", 0, Ptr) ;dwFlags
         break
      
      if !iou_hInternet := DllCall("wininet\InternetOpenUrl", Ptr, io_hInternet, "str", url, "str", "", "uint", 0, "uint", 0x80000000, "uint", 0)
         break
      
      VarSetCapacity(buffer_len, 4, 0) 
      Loop
      {         
         if A_Index = 3
            break 2
         
         VarSetCapacity(buffer, NumGet(&buffer_len+0, "UInt"))
         hqi := DllCall("wininet\HttpQueryInfo", Ptr, iou_hInternet, "uint", QueryInfoFlag, Ptr, &buffer, Ptr, &buffer_len, "uint", 0)
      } Until hqi
      Error := ""
   }
   
   DllCall("wininet\InternetCloseHandle",  Ptr, iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  Ptr, io_hInternet)
   DllCall("FreeLibrary", Ptr, hModule)
   
   Return, Error ? -1 : StrGet(&buffer)
}

Только чем это лучше, чем

pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1")
pWHttp.Open("GET", "https://docs.google.com/uc?export=download&id=0B7FildjsrNkILWhYVHYwanJLS3c", False)    
pWHttp.Send()
MsgBox, % pWHttp.getAllResponseHeaders()
pWHttp := ""

?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

22

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Браво teadrinker! Ещё и короче оригинала.

Только чем это лучше, чем

Как чем, смысл затеи узнать данные файла до его скачивания, особенно если файл большой.


url = http://ru.download.nvidia.com/Windows/335.23/335.23-desktop-win8-win7-winvista-64bit-international-whql.exe

pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1")
pWHttp.Open("GET", url, False)    
pWHttp.Send()
MsgBox, % pWHttp.getAllResponseHeaders()
pWHttp := ""
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

23

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

url := "http://ru.download.nvidia.com/Windows/335.23/335.23-desktop-win8-win7-winvista-64bit-international-whql.exe"

pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1")
pWHttp.Open("GET", url, true)    
pWHttp.Send()
Loop
{
   if (A_Index = 10 && Error := 1)
      break

   Sleep, 1000
   try if AllResponseHeaders := pWHttp.getAllResponseHeaders()
      break
   catch
      continue
}
pWHttp := ""
MsgBox, % Error ? "Время ожидания истекло" : AllResponseHeaders
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

24

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Хм... Я делал подобные попытки, но видимо как то не так.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

25

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

pWHttp.Open("GET", url, true)

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

26

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

А если сервер не особо доступен, и десяти секунд будет мало, разве способ HttpQueryInfo не более "правилен"?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

27

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

pWHttp.Open("GET", url, true)

Знаю, так и пробовал. В AhkSpy также обновление сделано.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

28

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

serzh82saratov пишет:

А если сервер не особо доступен, и десяти секунд будет мало, разве способ HttpQueryInfo не более "правилен"?

Тут уже точно к знатокам нужно. Я думаю, что эти два метода почти аналогичны, только в первом случае будет ждать бесконечное/неизвестное время, пока не будет доступна информация. Во втором варианте приемлемое время можно указать явно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

29

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

в первом случае будет ждать бесконечное/неизвестное время, пока не будет доступна информация.

Тут уже по вкусам, кому как.

WinHttpRequest хорош asynchronous mode, можно запустить кучу "закачек" (но только в оперативку?), а есть варианты нескольких закачек в файл из одного процесса AutoHotkey ?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

30

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Не думаю.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

31

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Наверно это стоить поместить в Коллекцию!

32

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

А на какую тему, именно определение расширения? Тут есть одна фишка — определение через реестр про типу данных.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

33 (изменено: Malcev, 2014-05-16 14:07:32)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

url := "http://ru.download.nvidia.com/Windows/335.23/335.23-desktop-win8-win7-winvista-64bit-international-whql.exe"

pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1")
pWHttp.Open("GET", url, true)    
pWHttp.Send()
Loop
{
   if (A_Index = 10 && Error := 1)
      break

   Sleep, 1000
   try if AllResponseHeaders := pWHttp.getAllResponseHeaders()
      break
   catch
      continue
}
pWHttp := ""
MsgBox, % Error ? "Время ожидания истекло" : AllResponseHeaders

Так этим кодом расширение не определяется.
На оф.форуме один форумчанин ответил, что думает что можно как-то  качать через httpRequest.ahk так чтобы не перегружался буфер.
Но там в такие дебри лезть надо....
http://www.autohotkey.com/board/topic/6 … /?p=650791

34

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Но это работает только в комплексе, для некоторых ссылок не работает


Download("http://avatars-fast.yandex.net/get-direct/R85qdm4hRHr-gA65dkojGA/y90")

Да и не сильно отличается от того что в Content-Type.

Так этим кодом расширение не определяется.

Так ведь наверное потому что просто нет ничего связанного с разбором инфо, у тебя же уже всё для этого есть. Так вроде всё определяет:


url = https://docs.google.com/uc?export=download&id=0B7FildjsrNkILWhYVHYwanJLS3c
url = http://ahkscript.org/download/ahk-install.exe 
url = http://avatars-fast.yandex.net/get-direct/R85qdm4hRHr-gA65dkojGA/y90
 
Download(url)

Download(url)
{
    Global Path, Location, FullSize, KBSize
    Location = %url%
    Info := HttpQueryInfo(Location, 22) 
    RegexMatch(Info, "\RContent-Disposition: .*?filename=""(?<D>.*?)""", C)  
    If CD !=  
        Path := CD
    Else
    { 
        RegexMatch(Info, "\RContent-Type: .*?/(?<T>.*?)\R", C)   
        SplitPath, Location, FileName, , Ext, NameNoExt 
        if (ext = "" && CT != "")
            Path := NameNoExt "." CT 
        Else
            Path := FileName
    }
    RegexMatch(Info, "\RContent-Length: (?<L>.*?)\R", C)  
    FullSize := CL
    MsgBox % Path "`n`n" KBSize := RTrim(t:=FullSize/1000, "0") "kb"
    Progress, H80, , Downloading..., %Path% Download
    SetTimer, GetSize, 100 
    UrlDownloadToFile, %Location%, %Path%  
    SetTimer, GetSize, -1 
    Return
}

GetSize: 
    FileOpen(Path, "r")
    FileGetSize, FSize, %Path%
    UpdateSize := Ceil((FSize / FullSize) * 100)   
    Progress, %UpdateSize%, %UpdateSize%`% Complete, Downloading... 
        , % RTrim(t:=FSize/1000, "0") "kb / " KBSize " || " Path 
Return

HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="")
{
   hModule := DllCall("LoadLibrary", "str", "wininet.dll", Ptr)
   AccessType := Proxy = "" ? 1 : 3
   
   Loop 1
   {
      Error := 1
      if !io_hInternet := DllCall("wininet\InternetOpen", "str", "", "uint", AccessType, "str", Proxy, "str", ProxyBypass, "uint", 0, Ptr) ;dwFlags
         break
      
      if !iou_hInternet := DllCall("wininet\InternetOpenUrl", Ptr, io_hInternet, "str", url, "str", "", "uint", 0, "uint", 0x80000000, "uint", 0)
         break
      
      VarSetCapacity(buffer_len, 4, 0) 
      Loop
      {         
         if A_Index = 3
            break 2
         
         VarSetCapacity(buffer, NumGet(&buffer_len+0, "UInt"))
         hqi := DllCall("wininet\HttpQueryInfo", Ptr, iou_hInternet, "uint", QueryInfoFlag, Ptr, &buffer, Ptr, &buffer_len, "uint", 0)
      } Until hqi
      Error := ""
   }
   
   DllCall("wininet\InternetCloseHandle",  Ptr, iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  Ptr, io_hInternet)
   DllCall("FreeLibrary", Ptr, hModule)
   
   Return, Error ? -1 : StrGet(&buffer)
}
 
Esc::   
    ExitApp
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

35

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Табличка 100% Downloading не исчезает после закачки.

36

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Сделай свой прогресс.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

37 (изменено: Malcev, 2014-05-16 16:00:38)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Немного переделал прогресс.
По-моему отличное решение получилось.
serzh82saratov и teadrinker огромный РЕСПЕКТ
Апдейт, Баг обнаружил - при несуществующей ссылке он все равно что-то качает либо подвисает.
Надо добавить парсинг на ответ 404 Not Found.
Может как-то так?

Info := HttpQueryInfo(Location, 22) 
If (Info ~= "404 Not Found")
   msgbox Error

url = http://ahkscript.org/downl45oad/ahk-install1.exe 

 
Download(url)

Download(url)
{
    Global Path, Location, FullSize, KBSize
    Location = %url%
    Info := HttpQueryInfo(Location, 22) 
    RegexMatch(Info, "\RContent-Disposition: .*?filename=""(?<D>.*?)""", C)  
    If CD !=  
        Path := CD
    Else
    { 
        RegexMatch(Info, "\RContent-Type: .*?/(?<T>.*?)\R", C)   
        SplitPath, Location, FileName, , Ext, NameNoExt 
        if (ext = "" && CT != "")
            Path := NameNoExt "." CT 
        Else
            Path := FileName
    }
    RegexMatch(Info, "\RContent-Length: (?<L>.*?)\R", C)  
    FullSize := CL
    MsgBox % Path "`n`n" KBSize := RTrim(t:=FullSize/1000, "0") "kb"
    SetTimer, GetSize, 100 
    UrlDownloadToFile, %Location%, %Path%  
    msgbox Done
    Return
}

GetSize: 
    FileOpen(Path, "r")
    FileGetSize, FSize, %Path%
    UpdateSize := Ceil((FSize / FullSize) * 100)   
    Progress, %UpdateSize%, %UpdateSize%`% Complete, Downloading... 
        , % RTrim(t:=FSize/1000, "0") "kb / " KBSize " || " Path
    if (UpdateSize = 100)
    {
       SetTimer, GetSize, off
       Progress, off  
    }
Return

HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="")
{
   hModule := DllCall("LoadLibrary", "str", "wininet.dll", Ptr)
   AccessType := Proxy = "" ? 1 : 3
   
   Loop 1
   {
      Error := 1
      if !io_hInternet := DllCall("wininet\InternetOpen", "str", "", "uint", AccessType, "str", Proxy, "str", ProxyBypass, "uint", 0, Ptr) ;dwFlags
         break
      
      if !iou_hInternet := DllCall("wininet\InternetOpenUrl", Ptr, io_hInternet, "str", url, "str", "", "uint", 0, "uint", 0x80000000, "uint", 0)
         break
      
      VarSetCapacity(buffer_len, 4, 0) 
      Loop
      {         
         if A_Index = 3
            break 2
         
         VarSetCapacity(buffer, NumGet(&buffer_len+0, "UInt"))
         hqi := DllCall("wininet\HttpQueryInfo", Ptr, iou_hInternet, "uint", QueryInfoFlag, Ptr, &buffer, Ptr, &buffer_len, "uint", 0)
      } Until hqi
      Error := ""
   }
   
   DllCall("wininet\InternetCloseHandle",  Ptr, iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  Ptr, io_hInternet)
   DllCall("FreeLibrary", Ptr, hModule)
   
   Return, Error ? -1 : StrGet(&buffer)
}
 
Esc::   
    ExitApp

38 (изменено: Malcev, 2014-05-16 16:06:53)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Вот так вроде работает:

url = http://ahkscript.org/downl45oad/ahk-install1.exe 

 
Download(url)

Download(url)
{
    Global Path, Location, FullSize, KBSize
    Location = %url%
    Info := HttpQueryInfo(Location, 22)
    If (Info ~= "404 Not Found")
    {
       msgbox Error
       return
    } 
    RegexMatch(Info, "\RContent-Disposition: .*?filename=""(?<D>.*?)""", C)  
    If CD !=  
        Path := CD
    Else
    { 
        RegexMatch(Info, "\RContent-Type: .*?/(?<T>.*?)\R", C)   
        SplitPath, Location, FileName, , Ext, NameNoExt 
        if (ext = "" && CT != "")
            Path := NameNoExt "." CT 
        Else
            Path := FileName
    }
    RegexMatch(Info, "\RContent-Length: (?<L>.*?)\R", C)  
    FullSize := CL
    MsgBox % Path "`n`n" KBSize := RTrim(t:=FullSize/1000, "0") "kb"
    SetTimer, GetSize, 100 
    UrlDownloadToFile, %Location%, %Path%  
    msgbox Done
    Return
}

GetSize: 
    FileOpen(Path, "r")
    FileGetSize, FSize, %Path%
    UpdateSize := Ceil((FSize / FullSize) * 100)   
    Progress, %UpdateSize%, %UpdateSize%`% Complete, Downloading... 
        , % RTrim(t:=FSize/1000, "0") "kb / " KBSize " || " Path
    if (UpdateSize = 100)
    {
       SetTimer, GetSize, off
       Progress, off  
    }
Return

HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="")
{
   hModule := DllCall("LoadLibrary", "str", "wininet.dll", Ptr)
   AccessType := Proxy = "" ? 1 : 3
   
   Loop 1
   {
      Error := 1
      if !io_hInternet := DllCall("wininet\InternetOpen", "str", "", "uint", AccessType, "str", Proxy, "str", ProxyBypass, "uint", 0, Ptr) ;dwFlags
         break
      
      if !iou_hInternet := DllCall("wininet\InternetOpenUrl", Ptr, io_hInternet, "str", url, "str", "", "uint", 0, "uint", 0x80000000, "uint", 0)
         break
      
      VarSetCapacity(buffer_len, 4, 0) 
      Loop
      {         
         if A_Index = 3
            break 2
         
         VarSetCapacity(buffer, NumGet(&buffer_len+0, "UInt"))
         hqi := DllCall("wininet\HttpQueryInfo", Ptr, iou_hInternet, "uint", QueryInfoFlag, Ptr, &buffer, Ptr, &buffer_len, "uint", 0)
      } Until hqi
      Error := ""
   }
   
   DllCall("wininet\InternetCloseHandle",  Ptr, iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  Ptr, io_hInternet)
   DllCall("FreeLibrary", Ptr, hModule)
   
   Return, Error ? -1 : StrGet(&buffer)
}
 
Esc::   
    ExitApp

39

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Malcev пишет:

По-моему отличное решение получилось.

Не пойму, зачем там создаётся лишняя переменная?

Location = %url%
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

40 (изменено: serzh82saratov, 2014-05-16 16:33:44)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Где то так.


url = http://ahkscript.org/download/ahk-install.exe 
url = http://ahkscript.org/downl45oad/ahk-install1.exe
 
MsgBox % Download(url) 
Return

Download(Location)
{
    Global Path, FullSize, KBSize 
    Info := HttpQueryInfo(Location, 22)  
    RegexMatch(Info, ".*? (.*?)\R", stat)
    If !InStr(stat1, "200 OK")
        Return "Error " stat1
    RegexMatch(Info, "\RContent-Disposition: .*?filename=""(?<D>.*?)""", C)  
    If CD !=  
        Path := CD
    Else
    { 
        RegexMatch(Info, "\RContent-Type: .*?/(?<T>.*?)\R", C)   
        SplitPath, Location, FileName, , Ext, NameNoExt 
        if (ext = "" && CT != "")
            Path := NameNoExt "." CT 
        Else
            Path := FileName
    }
    RegexMatch(Info, "\RContent-Length: (?<L>.*?)\R", C)  
    FullSize := CL
    MsgBox % Path "`n`n" KBSize := RTrim(t:=FullSize/1024, "0") "kb" 
    SetTimer, GetSize, 100 
    UrlDownloadToFile, %Location%, %Path%   
    Return "Complete"
}

GetSize: 
    FileOpen(Path, "r")
    FileGetSize, FSize, %Path%
    UpdateSize := Ceil((FSize / FullSize) * 100)   
    Progress, %UpdateSize%, %UpdateSize%`% Complete, Downloading... 
        , % RTrim(t:=FSize/1024, "0") "kb / " KBSize " || " Path
    if (UpdateSize = 100)
    {
       SetTimer, GetSize, off
       Progress, off  
    }
    Return
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

41

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

serzh82saratov пишет:
RegexMatch(Info, "\RContent-Disposition: .*?filename=""(?<D>.*?)""", C)

Regex неверный, по-моему. Разве есть гарантия, что Content-Disposition не будет первой строчкой?

serzh82saratov пишет:
MsgBox % Path "`n`n" KBSize := RTrim(t:=FullSize/1000, "0") "kb" 

Сколько байтов в килобайте, по-твоему?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

42

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Regex неверный, по-моему. Разве есть гарантия, что Content-Disposition не будет первой строчкой?

Там первой строкой всегда статус:

HTTP/1.1 200 OK

Сколько байтов в килобайте, по-твоему?

Переделал, всё осталось с забугорного оригинала. Но теперь циферки не красивые.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

43

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

serzh82saratov пишет:

Но теперь циферки не красивые.

А что мешает округлить до определённого знака?
Обозначение килобайта — KB или КБ, а "kb" можно с килобитами перепутать.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

44 (изменено: serzh82saratov, 2014-05-16 17:56:25)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.


url = http://ahkscript.org/download/ahk-install.exe 
 
MsgBox % Download(url) 
Return 

Download(Location)
{
    Global Path, FullSize, KBSize 
    Info := HttpQueryInfo(Location, 22)  
    RegexMatch(Info, ".*? (.*?)\R", stat)
    If !InStr(stat1, "200 OK")
        Return "Error: " stat1
    RegexMatch(Info, "\RContent-Disposition: .*?filename=""(?<D>.*?)""", C)   
    If CD !=  
        Path := CD
    Else
    { 
        SplitPath, Location, FileName, , Ext, NameNoExt 
        RegexMatch(Info, "\RContent-Type: (.*?/(.*?))\R", CT)   
        RegRead, ExtMIME, HKEY_CLASSES_ROOT, MIME\Database\Content Type\%CT1%, Extension  
        If (ExtMIME != "")
           Path := NameNoExt ExtMIME
        Else If (Ext = "" && CT2 != "")
            Path := NameNoExt "." CT2
        Else
            Path := FileName
    }
    If !Path
        Return "Error: Path not found"  
    RegexMatch(Info, "\RContent-Length: (?<L>.*?)\R", C), FullSize := CL
    MsgBox % Path "`n`n" KBSize := Floor(FullSize/1024) "KB"
    SetTimer, GetSize, 100 
    UrlDownloadToFile, %Location%, %Path%   
    SetTimer, GetSize, -1
    Progress, Hide
    Return "Complete"
}

GetSize: 
    FSize := FileOpen(Path, "r").Length 
    Percent := Floor((FSize / FullSize) * 100)  
    Progress, %Percent%, %Percent%`% Complete, Downloading... 
        , % Floor(FSize/1024) "KB / " KBSize " || " Path 
    Return
 
Esc::   
    ExitApp

HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="")
{
   hModule := DllCall("LoadLibrary", "str", "wininet.dll", Ptr)
   AccessType := Proxy = "" ? 1 : 3
   
   Loop 1
   {
      Error := 1
      if !io_hInternet := DllCall("wininet\InternetOpen", "str", "", "uint", AccessType, "str", Proxy, "str", ProxyBypass, "uint", 0, Ptr) ;dwFlags
         break
      
      if !iou_hInternet := DllCall("wininet\InternetOpenUrl", Ptr, io_hInternet, "str", url, "str", "", "uint", 0, "uint", 0x80000000, "uint", 0)
         break
      
      VarSetCapacity(buffer_len, 4, 0) 
      Loop
      {         
         if A_Index = 3
            break 2
         
         VarSetCapacity(buffer, NumGet(&buffer_len+0, "UInt"))
         hqi := DllCall("wininet\HttpQueryInfo", Ptr, iou_hInternet, "uint", QueryInfoFlag, Ptr, &buffer, Ptr, &buffer_len, "uint", 0)
      } Until hqi
      Error := ""
   }
   
   DllCall("wininet\InternetCloseHandle",  Ptr, iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  Ptr, io_hInternet)
   DllCall("FreeLibrary", Ptr, hModule)
   
   Return, Error ? -1 : StrGet(&buffer)
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

45

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

А почему перед

        Else
            Path := FileName

не использована возможность определения расширения через реестр?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

46 (изменено: Malcev, 2014-05-16 18:28:08)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Можно еще добавить запрет перезаписи файла.


SplitPath, Path, FileName, Dir, Ext, NameNoExt
n =
loop
{
   Path := Dir "\" nameNoExt n "." ext
   ifNotExist, %Path%
      break
   n++
}
UrlDownloadToFile, %Location%, %Path%

47

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

не использована возможность определения расширения через реестр?

Поправил.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

48

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

serzh82saratov пишет:
Percent := Ceil((FSize / FullSize) * 100)

Почему здесь Ceil()? значение 99.1 будет равно 100, что неправильно. Тут нужно Floor().

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

49

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Поправил 44й, выложил полный вариант.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

50

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Можно теперь и в коллекцию? Как я понял аналогов такого на AHK нету.

51

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Хороший скрипт для коллекции, но, как мне кажется, для полноценной работы он должен уметь обрабатывать следующие ситуации:

- файл с таким названием уже есть. Можно вторым параметром передать в Download(Location) флаг, как вести в таком случае - заменить старый файл, переименовать его, переименовать новый, отменить закачку или спросить пользователя;

- файл существует и заблокирован для записи другим процессом;

- у пользователя недостаточно прав для записи в папку Location;

- такой папки вообще нет.

Список можно расширить, но эти ситуации достаточно часто встречаются  и на их обработку нужно обратить внимание в первую очередь.

52

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Поддерживаю. Про недостаточно прав ничего не знаю. Как это проверить?
Небольшое исправление:

HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="")
{
   hModule := DllCall("LoadLibrary", Str, "wininet.dll", Ptr)
   AccessType := Proxy = "" ? 1 : 3
   
   Loop 1
   {
      if !io_hInternet := DllCall("wininet\InternetOpen", Str, "", UInt, AccessType, Str, Proxy, Str, ProxyBypass, UInt, 0, Ptr) ;dwFlags
         break
      
      if !iou_hInternet := DllCall("wininet\InternetOpenUrl", Ptr, io_hInternet, Str, url, Str, "", UInt, 0, UInt, 0x80000000, UInt, 0)
         break
      
      VarSetCapacity(buffer_len, 4, 0) 
      Loop
      {         
         if A_Index = 3
            break 2
         
         VarSetCapacity(buffer, NumGet(buffer_len, "UInt"))
         hqi := DllCall("wininet\HttpQueryInfo", Ptr, iou_hInternet, UInt, QueryInfoFlag, Ptr, &buffer, Ptr, &buffer_len, UInt, 0)
      } Until hqi
      success := 1
   }
   
   DllCall("wininet\InternetCloseHandle",  Ptr, iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  Ptr, io_hInternet)
   DllCall("FreeLibrary", Ptr, hModule)
   
   Return, success ? StrGet(&buffer) : -1
}

Один success вместо двух Error.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

53

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

teadrinker пишет:

Поддерживаю. Про недостаточно прав ничего не знаю. Как это проверить?

Наверно при помощи команды FileGetAttrib.

54

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

А как конкретно?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

55

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Например, так:

FileGetAttrib, Attributes, C:\WINDOWS
MsgBox, %Attributes%

The string returned will contain a subset of the letters in the string "RASHNDOCT":

R = READONLY
A = ARCHIVE
S = SYSTEM
H = HIDDEN
N = NORMAL
D = DIRECTORY
O = OFFLINE
C = COMPRESSED
T = TEMPORARY

То есть, как я понял, Attributes = R, когда недостаточно прав для записи.

56

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Нет, READONLY — это когда в свойствах папки стоит флажок "только для чтения", с правами это никак не связано вроде.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

57 (изменено: Irbis, 2014-05-16 23:52:05)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Это связано с правами доступа в ntfs. Например, пользователь без привилегий администратора попытается записать файл в папку windows.

58

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Может FileOpen(FileName, "w") и смотреть A_LastError?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

59 (изменено: serzh82saratov, 2014-05-17 12:00:09)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Ещё один способ закачки с прогрессом, так понимаю к нескольким закачкам из одного скрипта, тоже не имеет отношения.
http://www.autohotkey.com/board/topic/1 … ntry174581


DetectHiddenWindows, On 

url = http://ru.download.nvidia.com/Windows/335.23/335.23-desktop-win8-win7-winvista-64bit-international-whql.exe
url = http://ahkscript.org/download/ahk-install.exe 

splitpath,url,ofn
file := A_Desktop "\" ofn
MsgBox, % file "`n" url
If Download( url, file )  
    MsgBox Ok
Else
    MsgBox Error
Return


Download( url, file ) {
    static _init
    global _cu
    Splitpath,file, _dFile
    if ! init
    { 
        RegRead,SysNot,HKCU,AppEvents\Schemes\Apps\.Default\SystemNotification\.Current 
        Transform, SysNot, deref, %sysnot% 
        SysGet, m, MonitorWorkArea, 1
        y:=(mBottom-52-2),x:=(mRight-330-2),init:=1,VarSetCapacity(vt,4*11),nPar:="31132253353"
        Loop, Parse, nPar
            NumPut(RegisterCallback("DL_Progress","Fast",A_LoopField,A_Index-1),vt,4*(A_Index-1))
    } 
    VarSetCapacity(_cu,255),DllCall("shlwapi\PathCompactPathExW", "Str", _cu, "Str", url, "UInt", 50) 
    Progress,Hide CWFAFAF7 CT000020 CB445566 x%x% y%y% w330 h52 B1 FS8 WM700 WS700 FM8 ZH12 ZY3 C11,,%_cu%,AutoHotkeyProgress,Tahoma
    WinSet, Transparent,180, AutoHotkeyProgress
    SoundPlay, %SysNot% 
    re := DllCall("urlmon\URLDownloadToFileW", "Ptr", 0, "Str", url, "Str", file, "Uint", 0, "UintP", &vt)
    SoundPlay, %SysNot%
    Progress, Off
    Return re=0 ? 1 : 0
    }
    
DL_Progress( pthis, nP=0, nPMax=0, nSC=0, pST=0 ) {
    global _cu
    If (A_EventInfo=6) 
    { 
        Progress, Show
        Progress, % (P:=100*nP//nPMax),% "Downloading:     " Round(np/1024,1) " Kb / " 
                .  Round(npmax/1024) " Kb    [ " p "`% ]",%_cu%
    } 
    Return 0
}

Про этот параметр не до конца понял:

URLDownloadToFile function пишет:

pCaller

A pointer to the controlling IUnknown interface of the calling ActiveX component, if the caller is an ActiveX component. If the calling application is not an ActiveX component, this value can be set to NULL. Otherwise, the caller is a COM object that is contained in another component, such as an ActiveX control in the context of an HTML page. This parameter represents the outermost IUnknown of the calling component. The function attempts the download in the context of the ActiveX client framework, and allows the caller container to receive callbacks on the progress of the download.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

60

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

У меня этот код не работает. Обрати внимание на дату поста — 2008 г., написано под AHK-basic.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

61

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Irbis пишет:

Это связано с правами доступа в ntfs. Например, пользователь без привилегий администратора попытается записать файл в папку windows.

Не совсем понял, если права доступа есть, этот атрибут можно просто снять (так же, как и поставить).

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

62

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

teadrinker пишет:

У меня этот код не работает. Обрати внимание на дату поста — 2008 г., написано под AHK-basic.

Чутка поправил.
Ну у меня же работает, под анкх64 может не допилено.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

63

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

teadrinker пишет:

Не совсем понял, если права доступа есть, этот атрибут можно просто снять (так же, как и поставить).

По-моему, мы говорим про немного разные вещи. Смена атрибутов файла (R/O или R/W) ничего не даст, если в файловой системе не прописаны разрешения доступа. Даже запуск скрипта от имени администратора не поможет, если в перечне групп и пользователей убрать администраторов.

Пока не вижу решения, как силами AHK сменять действующие разрешения для файлов и папок, да и нужно ли это. На мой взгляд, самым простым способом будет, как предложил serzh82saratov в #58, открыть файл для записи и проверять код ошибки. Только сразу уж так "рубить с плеча не стоит" с параметром "w" , может пользователю не хочется перезаписывать существующий файл - параметр "a" подойдет и для создания, и файл не удалит. А дальше уже можно действовать по своему сценарию.

64 (изменено: serzh82saratov, 2014-05-17 21:49:45)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Не даёт мне покоя #59. Какое то подозрение, про 1 параметр. Если прописать как то некий ActiveX component, то может и асинхрон нарисуется... Не говоря уже про, по моему мнению, более правильный прогресс закачки.
Сабж интересен, но хочется увидеть в итоге полноценную качалку, несколько закачек с одного скрипта, пускай для начала, с созданием для каждой, своего процесса.

Irbis в #51 вызвался, пущай и запостит первенца в коллекцию, а Мы уже чем сможем.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

65

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Я только завтра смогу посмотреть, сейчас без компьютера.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

66

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

A pointer to the controlling IUnknown interface of the calling ActiveX component, if the caller is an ActiveX component. If the calling application is not an ActiveX component, this value can be set to NULL.

Адрес управляющего IUnknown-интерфейса вызывающего ActiveX-компонента, если вызывающий объект является ActiveX-компонентом. Если вызывающее приложение не является ActiveX-компонентом, это значение должно быть NULL.

AHK-скрипт не является ActiveX-компонентом, поэтому ничего другого здесь прописать нельзя.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

67

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

serzh82saratov пишет:

Irbis в #51 вызвался, пущай и запостит первенца в коллекцию, а Мы уже чем сможем.

Мне кажется, это будет несправедливо, моего кода в данном случае нет ни строчки... Так, пара идей только, и те пока не реализованы.

68

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Исправленный 44-ый пост.
Убрал чувствительность к регистру при парсинге инфо от сервера.

url = http://ahkscript.org/download/ahk-install.exe 
 
MsgBox % Download(url) 
Return 

Download(Location)
{
    Global Path, FullSize, KBSize 
    Info := HttpQueryInfo(Location, 22)  
    RegexMatch(Info, "i).*? (.*?)\R", stat)
    If !InStr(stat1, "200 OK")
        Return "Error: " stat1
    RegexMatch(Info, "i)\RContent-Disposition: .*?filename=""(?<D>.*?)""", C)   
    If CD !=  
        Path := CD
    Else
    { 
        SplitPath, Location, FileName, , Ext, NameNoExt 
        RegexMatch(Info, "i)\RContent-Type: (.*?/(.*?))\R", CT)   
        RegRead, ExtMIME, HKEY_CLASSES_ROOT, MIME\Database\Content Type\%CT1%, Extension  
        If (ExtMIME != "")
           Path := NameNoExt ExtMIME
        Else If (Ext = "" && CT2 != "")
            Path := NameNoExt "." CT2
        Else
            Path := FileName
    }
    If !Path
        Return "Error: Path not found"  
    RegexMatch(Info, "i)\RContent-Length: (?<L>.*?)\R", C), FullSize := CL
    MsgBox % Path "`n`n" KBSize := Floor(FullSize/1024) "KB"
    SetTimer, GetSize, 100 
    UrlDownloadToFile, %Location%, %Path%   
    SetTimer, GetSize, -1
    Progress, Hide
    Return "Complete"
}

GetSize: 
    FSize := FileOpen(Path, "r").Length 
    Percent := Floor((FSize / FullSize) * 100)  
    Progress, %Percent%, %Percent%`% Complete, Downloading... 
        , % Floor(FSize/1024) "KB / " KBSize " || " Path 
    Return
 
Esc::   
    ExitApp

HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="")
{
   hModule := DllCall("LoadLibrary", "str", "wininet.dll", Ptr)
   AccessType := Proxy = "" ? 1 : 3
   
   Loop 1
   {
      Error := 1
      if !io_hInternet := DllCall("wininet\InternetOpen", "str", "", "uint", AccessType, "str", Proxy, "str", ProxyBypass, "uint", 0, Ptr) ;dwFlags
         break
      
      if !iou_hInternet := DllCall("wininet\InternetOpenUrl", Ptr, io_hInternet, "str", url, "str", "", "uint", 0, "uint", 0x80000000, "uint", 0)
         break
      
      VarSetCapacity(buffer_len, 4, 0) 
      Loop
      {         
         if A_Index = 3
            break 2
         
         VarSetCapacity(buffer, NumGet(&buffer_len+0, "UInt"))
         hqi := DllCall("wininet\HttpQueryInfo", Ptr, iou_hInternet, "uint", QueryInfoFlag, Ptr, &buffer, Ptr, &buffer_len, "uint", 0)
      } Until hqi
      Error := ""
   }
   
   DllCall("wininet\InternetCloseHandle",  Ptr, iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  Ptr, io_hInternet)
   DllCall("FreeLibrary", Ptr, hModule)
   
   Return, Error ? -1 : StrGet(&buffer)
}

69

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Тут надо бы регексы заменить на GetResponseHeader для надёжности, и HttpQueryInfo заменить на HEAD запрос как здесь http://forum.script-coding.com/viewtopi … 653#p83653 для упрощения. Там же и закачка частями, таймер проверки размера файла в этом случае не требуется. Получение имени файла выведи в отдельную функцию для наглядности дальнейших редакций. Будет достаточно времени, добавлю мульти закачку.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

70

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

А чем сейчас этот скрипт ненадежен?
Чем другой вариант лучше?

71

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

HttpQueryInfo заменить на HEAD запрос

Я поспешил, в случае такой ссылки:

url = https://docs.google.com/uc?export=download&id=0B7FildjsrNkILWhYVHYwanJLS3c

в HEAD запросе совсем не то что нужно.

oWHR.Option(6) := 0

и редиректы тут не помогают. Так что оставляем как есть.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

72 (изменено: YMP, 2014-06-09 13:08:03)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Можно с помощью GET получить нужные заголовки, скачав 1 байт. Размер можно извлечь из Content-Range.


url = https://docs.google.com/uc?export=download&id=0B7FildjsrNkILWhYVHYwanJLS3c
HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
HTTP.Open("GET", url)
HTTP.SetRequestHeader("Range", "bytes=0-0")
HTTP.Send()
MsgBox, % HTTP.GetAllResponseHeaders()

73

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

YMP
Чертовски любопытно!

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

74

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Диапазон можно обозначать и от конца файла. Вот так последний байт можно скачать:


HTTP.SetRequestHeader("Range", "bytes=-1")

Если сервер не поддерживает диапазоны, то, как я понимаю, в свойстве Status должен быть код ошибки. Но размер файла в таком случае остаётся неизвестным. Вряд ли в заголовках он будет обозначен.

75

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

И в таком случае опять же пользовать HttpQueryInfo? Тогда уже смысл этого метода теряется.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

76 (изменено: YMP, 2014-06-09 15:27:15)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Вопрос в том, как HttpQueryInfo получает эти заголовки. Как ещё, если не отправляя какой-то запрос? А если так, то что мешает сделать то же объектом HTTP? Запрос HEAD, как мы видим, не годится. Может, она использует GET так же, как я. Надо бы найти сервер без поддержки диапазонов и проверить на нём работу HttpQueryInfo. Иначе откуда уверенность, что она там сработает?

Хотя да, думаю, она может просто остановить приём данных после получения заголовков.

77

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Кажется с github любой файл, уточнить с телефона не могу.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

78

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Апдейт мессаджа не видел. .Значит всё таки по вашему как...

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

79

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Хотя да, думаю, она может просто остановить приём данных после получения заголовков.

Насколько помню, в этих случаях оно качает файл целиком. Если речь про гет запрос, без возможности сервера отдавать диапазонами.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

80

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Насколько помню, в этих случаях оно качает файл целиком. Если речь про гет запрос, без возможности сервера отдавать диапазонами.

HttpQueryInfo вполне может и не качать. Как только скачались заголовки, функция может прекратить приём данных, т.к. ей больше ничего не нужно.

81

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

А чем HttpQueryInfo не устраивает?
В чем его минусы?

82

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Да всем устраивает, просто рассуждения о более коротком коде.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

83

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Разбираемся, как что работает, какие есть возможности.

84

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

HttpQueryInfo - это аналог:

url = https://www.autohotkey.com/download/AutoHotkeyInstall.exe
req := ComObjCreate("MSXML2.XMLHTTP.6.0")
req.Open("GET", url, true)
req.send()
while req.readyState <2   ; HEADERS_RECEIVED
   sleep 10
msgbox % req.GetAllResponseHeaders()

С Microsoft.XMLHTTP, Msxml2.XMLHTTP, Msxml2.XMLHTTP.3.0, WinHttpRequest такого провернуть не получится.
Ну и непонятно, почему мы считали, что после отправки запроса на сервер и после получения заголовков придется ждать получение тела ответа.

url = https://www.autohotkey.com/download/AutoHotkeyInstall.exe
req := ComObjCreate("WinHttp.WinHttpRequest.5.1")

a := a_tickcount
req.Open("GET", url)
req.send()
req.GetAllResponseHeaders()
msgbox % a_tickcount - a

a := a_tickcount
req.ResponseBody
msgbox % a_tickcount - a

85 (изменено: Malcev, 2018-09-24 00:48:21)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

Размер надёжней получать через MaxIndex().

url := "https://www.dropbox.com/sh/j1msw4e8dup2c5q/AAANYUWXcyBDgxVGkveU7AFla?dl=1"
;url := "https://raw.githubusercontent.com/f5devcentral/f5-irule-editor/master/iRuler/Templates/Blank.txt" ;1 byte
;url := "https://raw.githubusercontent.com/SparkPost/java-sparkpost/master/src/main/resources/empty.txt" ;0 bytes

req := ComObjCreate("WinHttp.WinHttpRequest.5.1")
req.Open("GET", url)
req.send()
msgbox % req.getallresponseheaders()
Body := req.ResponseBody
if IsObject(Body)
   length := Body.MaxIndex() + 1
else
   length := 0
msgbox % length

Скачать используя буфер (не напрямую в память) можно либо, с ком объектами WinHttpRequest, XMLHTTP с использованием Range, что не везде поддерживается,
либо через WinInet, что и делает UrlDownloadToFile:
https://docs.microsoft.com/en-us/window … etreadfile
либо WinHttp:
https://docs.microsoft.com/en-us/window … tpreaddata
либо Urlmon:
https://docs.microsoft.com/en-us/previo … v%3dvs.85)

86 (изменено: Malcev, 2018-09-30 04:00:18)

Re: AHK: UrlDownloadToFile с таким же расширением, как и скачиваемый файл.

teadrinker пишет:

Небольшое исправление:

HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="")
{
   hModule := DllCall("LoadLibrary", Str, "wininet.dll", Ptr)
   AccessType := Proxy = "" ? 1 : 3
   
   Loop 1
   {
      if !io_hInternet := DllCall("wininet\InternetOpen", Str, "", UInt, AccessType, Str, Proxy, Str, ProxyBypass, UInt, 0, Ptr) ;dwFlags
         break
      
      if !iou_hInternet := DllCall("wininet\InternetOpenUrl", Ptr, io_hInternet, Str, url, Str, "", UInt, 0, UInt, 0x80000000, UInt, 0)
         break
      
      VarSetCapacity(buffer_len, 4, 0) 
      Loop
      {         
         if A_Index = 3
            break 2
         
         VarSetCapacity(buffer, NumGet(buffer_len, "UInt"))
         hqi := DllCall("wininet\HttpQueryInfo", Ptr, iou_hInternet, UInt, QueryInfoFlag, Ptr, &buffer, Ptr, &buffer_len, UInt, 0)
      } Until hqi
      success := 1
   }
   
   DllCall("wininet\InternetCloseHandle",  Ptr, iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  Ptr, io_hInternet)
   DllCall("FreeLibrary", Ptr, hModule)
   
   Return, success ? StrGet(&buffer) : -1
}

Один success вместо двух Error.

Тут ошибка:

link := "https://www.google.com/maps/vt/pb=!1m5!1m4!1i12!2i4645!3i2509!4i128!2m2!1e1!3i810!3m9!2sru!3slv!5e1105!12m1!1e4!12m1!1e47!12m1!1e3!4e0!5m1!1e0!23i4111425!23i1358757!23i1358902"
msgbox % HttpQueryInfo(link)


HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="")
{
   hModule := DllCall("LoadLibrary", Str, "wininet.dll", Ptr)
   AccessType := Proxy = "" ? 1 : 3
   
   Loop 1
   {
      if !io_hInternet := DllCall("wininet\InternetOpen", Str, "", UInt, AccessType, Str, Proxy, Str, ProxyBypass, UInt, 0, Ptr) ;dwFlags
         break
      
      if !iou_hInternet := DllCall("wininet\InternetOpenUrl", Ptr, io_hInternet, Str, url, Str, "", UInt, 0, UInt, 0x80000000, UInt, 0)
         break
      
      VarSetCapacity(buffer_len, 4, 0) 
      Loop
      {         
         if A_Index = 3
            break 2
         
         VarSetCapacity(buffer, NumGet(buffer_len, "UInt"))
         hqi := DllCall("wininet\HttpQueryInfo", Ptr, iou_hInternet, UInt, QueryInfoFlag, Ptr, &buffer, Ptr, &buffer_len, UInt, 0)
      } Until hqi
      success := 1
   }
   
   DllCall("wininet\InternetCloseHandle",  Ptr, iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  Ptr, io_hInternet)
   DllCall("FreeLibrary", Ptr, hModule)
   
   Return, success ? StrGet(&buffer) : -1
}

Чтобы такого избежать нужно указывать lpszAgent в InternetOpen запросе:

link := "https://www.google.com/maps/vt/pb=!1m5!1m4!1i12!2i4645!3i2509!4i128!2m2!1e1!3i810!3m9!2sru!3slv!5e1105!12m1!1e4!12m1!1e47!12m1!1e3!4e0!5m1!1e0!23i4111425!23i1358757!23i1358902"
msgbox % HttpQueryInfo(link)


HttpQueryInfo(URL, QueryInfoFlag=21, Proxy="", ProxyBypass="")
{
   hModule := DllCall("LoadLibrary", Str, "wininet.dll", Ptr)
   AccessType := Proxy = "" ? 1 : 3
   
   Loop 1
   {
      if !io_hInternet := DllCall("wininet\InternetOpen", Str, "autohotkey", UInt, AccessType, Str, Proxy, Str, ProxyBypass, UInt, 0, Ptr) ;dwFlags
         break
      
      if !iou_hInternet := DllCall("wininet\InternetOpenUrl", Ptr, io_hInternet, Str, url, Str, "", UInt, 0, UInt, 0x80000000, UInt, 0)
         break
      
      VarSetCapacity(buffer_len, 4, 0) 
      Loop
      {         
         if A_Index = 3
            break 2
         
         VarSetCapacity(buffer, NumGet(buffer_len, "UInt"))
         hqi := DllCall("wininet\HttpQueryInfo", Ptr, iou_hInternet, UInt, QueryInfoFlag, Ptr, &buffer, Ptr, &buffer_len, UInt, 0)
      } Until hqi
      success := 1
   }
   
   DllCall("wininet\InternetCloseHandle",  Ptr, iou_hInternet)
   DllCall("wininet\InternetCloseHandle",  Ptr, io_hInternet)
   DllCall("FreeLibrary", Ptr, hModule)
   
   Return, success ? StrGet(&buffer) : -1
}