Получение нестандартных аргументов командной строки

Тема в разделе "WASM.WIN32", создана пользователем _Sysman_, 19 дек 2004.

  1. _Sysman_

    _Sysman_ Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    50
    Адрес:
    Ukraine
    Нужно сделать программу-downloader. Программа вызывается из другой программы, закачивает и сохраняет выбранный файл. Параметры передаются в командной строке вида:

    downloader.exe http://tralala.com/etc/my/15.html C:\page1.htm,

    где первый параметр - адрес файла в инете, а второй - адрес на локальном компьютере.

    Как можно выделить каждый из параметров? На форуме уже обсуждалась эта тема, но приведённые там способы не подходят (не работают со строкой вида http://...).

    Конструкция вида invoke ArgCl,1,addr buffer тоже не работает корректно. Так как можно выделить такие параметры и ешё, как можно известить вызвавшую программу, что файл закачан?
     
  2. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Ну можно так, например:


    Код (Text):
    1. SplitCommStr proc uses esi lpComStr:DWORD
    2.     LOCAL CommStr[512]    :BYTE    
    3.     LOCAL Param1[256]     :BYTE
    4.     LOCAL Param2[256]     :BYTE
    5.    
    6.     ;копия строки, чтобы исходная была неизменной
    7.     invoke lstrcpy,ADDR CommStr,lpComStr
    8.     invoke lstrlen,ADDR CommStr
    9.     lea esi,CommStr
    10.     add esi,eax
    11.     dec esi
    12.     std
    13. @@: inc esi                ;от конца строки назад просмотр
    14.     lodsw
    15.     cmp ax,5C3Ah           ;пока встретится ":\"
    16.     jne @B
    17.     mov byte ptr [esi],0   ;разделение строки на две
    18.     inc esi                ;адрес начала второй части
    19.     cld
    20.     invoke lstrcpy,ADDR Param1,ADDR CommStr
    21.     invoke lstrcpy,ADDR Param2,esi
    22.    
    23.     invoke MessageBox,NULL,ADDR Param1,ADDR Param2,MB_OK
    24.     ret
    25. SplitCommStr endp
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    А сообщить вызвавшей проге, что файл закачан, можно через

    SendMessage CallerWnd,WM_USER+777,wP,lP и заодно ещё два каких нибудь параметра передать (wP,lP)

    В WndProc ловить сообщение WM_USER+777 и реагировать
     
  4. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    _Sysman_

    Что не стандартного в аргументах?

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



    как можно известить вызвавшую программу

    Почитай про способы межпроцессного взаимодействия. Например, признаком завершения загрузки может быть завершение работы программы-качалки.



    cresta

    сообщить вызвавшей проге ... можно через

    SendMessage


    Для этого качалка должна знать дескриптор окна вызвавшей ее программы, т.е. появляется ограничение на тип (gui/con) родителя + качалка должна иметь код определяющий дескриптор окна.
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    q_q



    Если вызывает консоль, то хэндла конечно нет, а если GUI, то что мешает допустим третьим параметром командной строки передать дескриптор окна? Завершение работы качалки конечно более универсальный вариант, но на мой взгляд (может ошибаюсь) проще добыть третий параметр из ком. строки.
     
  6. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Про работу CreateProcess применительно к созданию дочерних процессов смотрите на сайте http://www.catch22.net
     
  7. Arvensis

    Arvensis New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2004
    Сообщения:
    72
    Адрес:
    Russia
    Как насчет такой схемы?

    Качалка при запуске создает семафор, и периодически его обновляет, записывая закачанный процент. Программа-родитель по таймеру опрашивает состояние семафора, заодно и функциональность повышается - можно не только определить завершение закачки, но и прикинуть, когда она закончится. Возможны варианты - например, семафор создает главная программа, а дочерняя наследует хэндл, но с наследованием я нифига из SDK не понял :dntknw:
     
  8. _Sysman_

    _Sysman_ Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    50
    Адрес:
    Ukraine
    Вообще то программа, запускающая качалку написана не на asm'е и не на C++, поэтому с ловлей сообщений придётся попотеть :)

    А идея сделать качалку в виде отдельной программы на asm'е возникла потому, что применив функцию URLDownloadToFile из URLMon.dll, оказалось что она не возвращает управление до тех пор, пока файл не скачается полностью (т. е. запустил юзер прогу и она у него "зависла" пока файл не докачался. А так как файлов предполагается скачивать много, то это очень как не к стати).

    Arvensis

    Семафор конечно хорошо. Но только если писать в реестр или куда нибудь на диск очень часто - зачем лишний раз фрагментировать диск? Проще наверное, если прога будет записывать скачанный файл только перед завершением своей работы - тогда останется определить существует ли файл и отличен ли его размер от нуля.



    [​IMG] _88430738__Downloader.rar
     
  9. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    _Sysman_

    Как можно выделить каждый из параметров? На форуме уже обсуждалась эта тема, но приведённые там способы не подходят (не работают со строкой вида http://...).



    Библиотечка CLASH решает проблему парсинга командных строк (где брал сам - уже не помню, скорее всего на сайте Iczelion'а). Проверено - работает как надо.
     
  10. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    А почему нельзя отдельный поток для URLDownloadToFile?
     
  11. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    CyberManiac

    > Библиотечка CLASH решает проблему парсинга командных строк



    Неужели это так сложно что нужно применять какую-то стороннюю "библиотечку" :derisive:
     
  12. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    _Sysman_



    А почему не сделать так: оформить твой закачивающий модуль не как ехе, а как dll, вызывать из главной проги процедуру в ней, которая будет запускать CreateThread по закачке, вызывающая прога замерзать не будет, в dll можно передавать все твои входные параметры раздельно, не надо ничего парсить. По-моему это лучше, чем ехе с командной строкой и её заморочками.



    P.S.

    Туда же можно передавать и хэндл окна, который примет сообщение об окончании закачки.
     
  13. _Sysman_

    _Sysman_ Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    50
    Адрес:
    Ukraine
    cresta







    Спасибо, так и сделаю
     
  14. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    проще добыть третий параметр

    Какие проблемы с определением момента завершения работы процесса?



    оформить твой закачивающий модуль ... как dll

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



    Arvensis

    Программа-родитель по таймеру опрашивает состояние семафора

    Таймер - это детский лепет. Ты тоже не имеешь представления о методах синхронизации? Читай Рихтера.



    _Sysman_

    Imho если ты не в состоянии самостоятельно разобрать командную строку, то потоками и закачками тебе рано заниматься.
     
  15. sl0n

    sl0n Мамонт дзена **

    Публикаций:
    0
    Регистрация:
    26 сен 2003
    Сообщения:
    703
    Насчёт того что писать даунлодер, не умея парсить командную строку нельзя это факт.



    Готовый даунлодер твоего плана писал векна и он где-то на сайте зомби валяется.
     
  16. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    q_q

    Никаких проблем нет с определением завершения процесса :) В случае с SendMessage нет необходимости делать даже это. Единственное телодвижение - отослать WM_USER. О монстрах: запустить из ехе другой ехе передавая ему командную строку и ожидать в таймере завершения процесса - способ гораздо более монструозный, чем вызов функции dll.



    А пожелание сначала научиться парсить строку, а затем запускать закачки и потоки - это как в анекдоте: сначала плавать научитесь, а затем мы вам воду в бассейн нальём :)
     
  17. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Asterix

    Неужели это так сложно что нужно применять какую-то стороннюю "библиотечку" :derisive:



    Не сложнее, чем изобрести велосипед. Но однозначно дольше, чем воспользоваться готовой и проверенной библиотекой, которую умные люди специально для этого сделали и подарили общественности.
     
  18. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    с SendMessage нет необходимости делать

    Что будет с потоком, вызвавшем SendMessage, если обработчик WM_USER+???? зависнет?



    ожидать в таймере завершения процесса

    Imho только нерадивые программисты могут использовать таймер для ожидания завершения процесса.



    пожелание сначала научиться парсить строку ... это как в анекдоте

    В анекдоте значит?

    По-твоему лучше писать кривые программы и обвинять microsoft?
     
  19. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    q_q



    Если есть опасения что обработчик зависнет, можно использовать PostMessage, и не ожидая отвиснет или нет, завершить поток закачки. А предложение использовать таймер реально звучало тут.



    Данную задачу я вижу примерно так:

    invoke SomeProcInDll,Par1,Par2...ParN

    из тела SomeProcInDll:

    invoke CreateThread...offset DownloadProc...

    ret

    из DownloadProc:

    invoke URLDownloadToFile

    invoke PostMessage,hWnd,WM_USER.......

    ret



    Как на твой взгляд более правильно и менее криво?
     
  20. _Sysman_

    _Sysman_ Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    50
    Адрес:
    Ukraine
    q_q



    Я всеми руками за - чтобы кривые программы не писать. Поэтому, если что-то не знаю - стараюсь узнать, спросить. И пишу что-то лишь тогда, когда разобрался в этом на 100% и знаю как это работает от А до Я со всеми возможностями и подробностями.