Обработка параметров коммандной строки

Тема в разделе "WASM.BEGINNERS", создана пользователем _Poly_Glot_, 25 июл 2007.

  1. _Poly_Glot_

    _Poly_Glot_ [poly] glot

    Публикаций:
    0
    Регистрация:
    25 июл 2007
    Сообщения:
    44
    Адрес:
    Санкт-Петербург
    Здрасьте все.
    Тут одна элементарнейшая прога не получается.

    В общем я хотел сделать прогу, которая при запуске проверяет переданные через коммандную строку ей параметры, и если
    в коммандной строке ничего нет, то появляется окошком с заголовком: "Ты запустил эту прогу без параметров в коммандной
    строке", а если в коммандной строке есть параметр, то параметр появляется в заголовке окна. Я всё сделал, почти получилось,
    только если запускать мою прогу в Olly DBG и указать в пункте меню отладчик=>параметры что-либо, то это появляется в
    заголовке. Но если указать что-нибудь в командной строке - то появляется надпись "Ты запустил эту прогу без параметров в
    коммандной строке", как будто ничего нету. В общем, укажите пожалуйста мою ошибку...

    Исходник с моей прогой и пояснениями прикладываю.

    И ещё, может у кого-нибудь есть исходничек проги, которая обрабатывает коммандную строку?
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    так проще
    Код (Text):
    1. .data
    2. cmd_args dd 0
    3.  
    4. invoke GetCommandLine
    5. invoke PathGetArgs,eax
    6. mov cmd_args,eax
    7. mov al,[eax]
    8. ;Если параметры заключены в кавычки - убрать кавычки!
    9. .IF al != 0
    10.     .IF al == '"'
    11.         invoke PathUnquoteSpaces,cmd_args
    12.         mov cmd_args,eax
    13.     .ENDIF
    14. .ENDIF
    15. xor ecx,ecx
    16.    invoke MessageBox,ecx,cmd_args,ecx,ecx
     
  3. _Poly_Glot_

    _Poly_Glot_ [poly] glot

    Публикаций:
    0
    Регистрация:
    25 июл 2007
    Сообщения:
    44
    Адрес:
    Санкт-Петербург
    Спасибо, буду разбираться, только можно пояснить несколько вещей:

    1) Что такое al != 0
    При чём тут восклицательный знак? Просто я не очень ещё разбираюсь во всех этих структурах

    2) Объясните пожалуйста, структуру условного оператора .IF-.ELSEIF-.ELSE-.ENDIF и знаки неравенства, ну или хотя бы ссылочку подкиньте про такие структуры. А то читаю туторы Айсилона, он это использует но не объясняет
     
  4. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    != означает неравенство, т.е. al не равен 0
     
  5. _Poly_Glot_

    _Poly_Glot_ [poly] glot

    Публикаций:
    0
    Регистрация:
    25 июл 2007
    Сообщения:
    44
    Адрес:
    Санкт-Петербург
    MSoft - спасибо.
    И ещё: Я не нашёл API ф-ций PathGetArgs и PathUnquoteSpace, хотя у меня справочник Win32.hlp что это за ф-ции?
     
  6. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    .IF-.ELSEIF-.ELSE-.ENDIF
    аналогичен подобной структуре во всех языках
    Код (Text):
    1. .if condition0
    2.  ;condition0 is true
    3.  ...
    4. .elseif condition1
    5.  ;condition1 is true
    6.  ...
    7. .else
    8.  ;both conditions are false
    9.  ...
    10. .endif ;end of struct
     
  7. _Poly_Glot_

    _Poly_Glot_ [poly] glot

    Публикаций:
    0
    Регистрация:
    25 июл 2007
    Сообщения:
    44
    Адрес:
    Санкт-Петербург
    RamMerLabs
    Спасибо, а какие есть знаки неравенства (<,>, и т.д), а то тут равенство это '==', а неравенство вообще ! =
     
  8. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    _Poly_Glot_
    Если юзаешь масм, можно юзать masmlib для парсинга аргументов.
     
  9. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    _Poly_Glot_

    < - меньше
    > - больше
    <= - меньше или равно
    >= - больше или равно
    == - равно
    != - не равно
    вроде ничего не забыл

    вообще есть доки по масму.
     
  10. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    Booster а как там функции называются?
    возможно а повторил колесо, но если кому интересно мой код для решения проблемы ниже.
    Он парсит параметры начиная с имени программы, если параметр должен содержать пробелы необходимо заключить его в кавычки.
    используемая структура:
    Код (Text):
    1. ARGUMENTS_DESCRIBE struct
    2.     ArgCount        dd ? ;argument count, use argGetArgumentsCount to get this value
    3.     lpArguments     dd ? ;pointer to array of points to arguments parameters (asciiz)
    4. ARGUMENTS_DESCRIBE ends
    5. ERROR_PARSE_INCONRRECT_ARGUMENT equ -1
    юзать примерно так (помоему красиво :):
    Код (Text):
    1.     ;parsing arguments
    2.     invoke GetCommandLine
    3.     mov esi, eax
    4.    
    5.     invoke argGetCount, eax ;получаем кол-во аргументов с именем самой программы
    6.     mov ArgDesc.ArgCount, eax ;записываем в структуру
    7.    
    8.     imul eax, eax, sizeof (LPDWORD) ;cчитаем размер для буффера указателей
    9.     invoke GlobalAlloc, GMEM_FIXED, eax ;выделяем память
    10.    
    11.     mov lpMem, eax ;cохраняем указатель
    12.     mov ArgDesc.lpArguments, eax ;заносим указатель в стуктуру описаную выше
    13.    
    14.     invoke argParse, offset ArgDesc, esi ;парсим, на выходе получам указатели на asciiz строки параметров
    15.    
    16.    
    17.     xor ebx, ebx ; обнуляем флаг присутствия хотя бы одного из нижеперечисленных параметров
    18.     invoke argLookUp, $CTA0("-h"), offset ArgDesc
    19.     or ebx, eax
    20.     invoke argLookUp, $CTA0("-?"), offset ArgDesc
    21.     or ebx, eax
    22.     invoke argLookUp, $CTA0("/?"), offset ArgDesc
    23.     or ebx, eax
    24.     invoke argLookUp, $CTA0("/h"), offset ArgDesc
    25.     .if (eax == TRUE) || ( ArgDesc.ArgCount == 1) || (ebx == TRUE)
    26.         ;вывод справки
    27.         ret
    28.     .endif
    так же есть функция для нахождения "пары" заданного аргумента:
    Код (Text):
    1. invoke argFindPair, $CTA0("-offx"), offset ArgDesc
    сам код:
    Код (Text):
    1. argSkipSpaces proc  uses eax;input\output param : esi
    2.    
    3. @@:
    4.     lodsb
    5.     cmp al, 0
    6.     je @f
    7.     cmp al, ' '
    8.     jne @f  
    9.     jmp @b
    10. @@:
    11.     dec esi
    12.     ret
    13.  
    14. argSkipSpaces endp
    15.  
    16. argSkipNonSpaces proc uses eax ;input\output param : esi
    17.    
    18. @@:
    19.     lodsb
    20.     cmp al, 0
    21.     je @f
    22.     cmp al, ' '
    23.     je @f  
    24.     jmp @b
    25. @@:
    26.     dec esi  
    27.     ret
    28.  
    29. argSkipNonSpaces endp
    30.  
    31. argSkipNonQuotes proc  uses eax;input\output param : edi
    32. @@:
    33.     lodsb
    34.     cmp al, 0
    35.     je @f
    36.     cmp al, '"'
    37.     je @f  
    38.     jmp @b
    39. @@:
    40.     dec esi
    41.     ret
    42. argSkipNonQuotes endp
    43.  
    44. argGetCount proc uses esi edi, lpszStr: DWORD;(with program name itself)
    45.  
    46.     mov esi, lpszStr
    47.     xor ecx, ecx
    48.     .if byte ptr [esi] == 0
    49.         xor eax, eax
    50.         ret
    51.     .endif
    52.     .repeat
    53.         .if byte ptr [esi] == '"'
    54.             inc esi
    55.             invoke argSkipNonQuotes
    56.             inc ecx
    57.             .break .if byte ptr [esi] == 0 ;if : "asdf\0
    58.             inc esi
    59.             .break .if byte ptr [esi] == 0
    60.         .else
    61.             invoke argSkipNonSpaces
    62.             inc ecx
    63.             .break .if byte ptr [esi] == 0
    64.         .endif
    65.         invoke argSkipSpaces
    66.         .break .if byte ptr [esi] == 0 
    67.     .until FALSE
    68.     mov eax, ecx
    69.        
    70.     ret
    71. argGetCount endp
    72.  
    73. argParse proc uses esi edi,  lpArgumentsDesc: DWORD, \;pointer to initialized ARGUMENTS_DESCRIBE,  see include file
    74.                             lpszStr: DWORD
    75.     mov edx, lpArgumentsDesc
    76.    
    77.     mov esi, lpszStr
    78.      
    79.     mov edi, (ARGUMENTS_DESCRIBE ptr [edx]).lpArguments
    80.     xor ecx, ecx
    81.  
    82.     .if byte ptr [esi] == 0
    83.         mov eax, ERROR_PARSE_INCONRRECT_ARGUMENT
    84.         ret
    85.     .endif
    86.     .repeat
    87.        
    88.         .if byte ptr [esi] == '"'
    89.             inc esi
    90.             mov eax, esi
    91.             stosd
    92.             invoke argSkipNonQuotes
    93.             inc ecx
    94.             .break .if byte ptr [esi] == 0 ;if : "asdf\0
    95.             mov byte ptr [esi], 0
    96.             inc esi
    97.             .break .if byte ptr [esi] == 0
    98.         .else
    99.             mov eax, esi
    100.             stosd
    101.             invoke argSkipNonSpaces
    102.             inc ecx
    103.             .break .if byte ptr [esi] == 0
    104.             mov byte ptr [esi], 0
    105.             inc esi
    106.         .endif
    107.         invoke argSkipSpaces
    108.         .break .if byte ptr [esi] == 0
    109.        
    110.     .until FALSE
    111.    
    112.     mov eax, (ARGUMENTS_DESCRIBE ptr [edx]).ArgCount
    113.     .if eax == ecx
    114.         mov eax, ERROR_SUCCESS
    115.     .else
    116.         mov eax, ERROR_PARSE_INCONRRECT_ARGUMENT
    117.     .endif
    118.     ret
    119. argParse endp
    120.  
    121. argFindPair proc uses esi edi, \
    122.               lpszFirstArg:DWORD, \ ;IN
    123.               lpArgDesc:DWORD   ;IN pointer to ARGUMENTS_DESCRIBE
    124.                                 ;returns pointer to pair argument
    125.    
    126.     mov eax, lpArgDesc
    127.     mov edi, (ARGUMENTS_DESCRIBE ptr [eax]).ArgCount
    128.     mov esi, (ARGUMENTS_DESCRIBE ptr [eax]).lpArguments
    129.     lodsd ;skip first argumen - application name
    130.     .while (edi != 1)
    131.         dec edi
    132.         lodsd
    133.         invoke lstrcmp, lpszFirstArg, eax
    134.         .break .if !eax
    135.     .endw
    136.     .if edi == 1
    137.         mov eax, FALSE
    138.     .else
    139.         mov eax, [esi]
    140.     .endif
    141.     ret
    142.  
    143. argFindPair endp
    144.  
    145. argLookUp proc uses edi esi,
    146.               lpszArg:DWORD, \      ;IN
    147.               lpArgDesc:DWORD   ;IN pointer to ARGUMENTS_DESCRIBE
    148.                                 ;returns TRUE if arument exists ELSE otherwise
    149.     mov eax, lpArgDesc
    150.     mov edi, (ARGUMENTS_DESCRIBE ptr [eax]).ArgCount
    151.     mov esi, (ARGUMENTS_DESCRIBE ptr [eax]).lpArguments
    152.    
    153.     lodsd ;skip first argumen - application name
    154.     .while (edi != 1)
    155.         lodsd
    156.         invoke lstrcmp, lpszArg, eax
    157.         .break .if !eax
    158.         dec edi  
    159.     .endw
    160.     .if !eax
    161.         mov eax, TRUE
    162.     .else
    163.         mov eax, FALSE
    164.     .endif
    165.     ret
    166.  
    167. argLookUp endp
    зы если кто будет юзать этот код и найдёт в нём баги просьба отписать в аську\личку
     
  11. roman_pro

    roman_pro New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2007
    Сообщения:
    291
    Всё написано за нас:

    GetCommandLineW + CommandLineToArgvW спасут отцов русской демократии :) Ну и WideCharToMultiByte если прога не юникодная.
     
  12. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    вообще-то да, только юникодовая
     
  13. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    они в shlwapi.dll
    нужно подключить
    include \masm32\include\shlwapi.inc
    includelib \masm32\lib\shlwapi.lib
     
  14. roman_pro

    roman_pro New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2007
    Сообщения:
    291
    Ну вообще-то, в ней проблем нет:

    А вот чисто юникодная это CommandLineToArgvW:

     
  15. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    rain
    Названия не помню (склероз), масма сейчас под рукой нету. В пакете масма есть справка по masmlib и там всё подробно описано. Распарсивает оно довольно хорошо, там тоже массив аргументов создаётся.
    Причём так как она в исходниках, то и портировать её можно.
     
  16. _Poly_Glot_

    _Poly_Glot_ [poly] glot

    Публикаций:
    0
    Регистрация:
    25 июл 2007
    Сообщения:
    44
    Адрес:
    Санкт-Петербург
    Спасибо всем. Буду разбираться =)