Главная
Форумы
Новые сообщения
Поиск сообщений
Что нового?
Новые сообщения
Новые ресурсы
Последняя активность
Ресурсы
Последние отзывы
Поиск ресурсов
Помощь форуму
ЧатTG
Вход
Регистрация
Что нового?
Поиск
Поиск
Искать только в заголовках
От:
Новые сообщения
Поиск сообщений
Меню
Вход
Регистрация
Приложение
Установить
Форумы
Форум программистов
Visual Basic 6 / Сценарии VBScript, JScript
Изучение основ языка
Принцип составления однострочных команд для метода Shell
JavaScript отключён. Чтобы полноценно использовать наш сайт, включите JavaScript в своём браузере.
Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно.
Вам необходимо обновить браузер или попробовать использовать
другой
.
Ответить в теме
Сообщение
[QUOTE="Dragokas, post: 163034, member: 6966"] [RIGHT][SIZE=3]Статья от 17.01.2013 Автор: [B]Dragokas[/B][/SIZE][B][COLOR=Blue][/COLOR][/B][/RIGHT] [B][COLOR=Blue] Принцип составления однострочных команд Batch[/COLOR][/B] Однострочные команды Batch используются там, где нет возможности написать команды в несколько строк, в случаях когда они объединены логикой и не могут выполнятся в разрыве друг от друга в разных сессиях интерпретатора. [COLOR=Green][B]Область применения:[/B][/COLOR] 1) Языки программирования высокого уровня 2) Реестр Windows (reg-файл) [COLOR=green][B]Пример логики связи:[/B][/COLOR] 1) Команды "удалить файлы a и b" [code=batch]del a del b[/CODE] можно выполнить отдельно: [code=vbnet]shell "cmd /c del a" shell "cmd /c del b"[/CODE] 2) Команды "вывести на экран сумму 1 + 1" [code=batch]Set /A n= 1 + 1 Echo %n%[/CODE] разрывать нельзя, так как значение переменной "n" будет утеряно. Чтобы составить сложный набор однострочных команд для выполнения в методе (процедуре, объекте) Shell другого ЯП нужно [B]сначала добиться успешной отработки Вашей конструкции в среде командного интерпретатора.[/B] Открываем консоль - Win + R (выполнить), CMD {Enter} Формируем однострочные команды, подставляя первой командой запуск самого EXE-файла интерпретатора: [code=batch]CMD.exe /C Echo Привет[/CODE] Если нужно выполнить несколько команд, строку команд обрамляем кавычками (согласно синтаксиса ключей CMD /?) а сами команды разделяются знаком "амперсанд" (&) [code=batch]::если файл "а" существует, скопировать его под именем "b". Удалить файл "c". cmd /c "if exist a copy a b& del c"[/CODE] Все кавычки, которые будут заключены внутрь считаются как единая строка и не бьются на отдельные токены. Об этом беспокоится не нужно. [code=batch]::Например, копирование файла с пробелами в пути и/или имени: cmd /c "copy "c:\my folder\a.txt" "c:\my folder\b.txt""[/CODE] Если участвует цикл FOR, в отличие от текста bat-файла, здесь спецсимволы не обрабатываются, поэтому % в цикле удваивать не нужно. Если команду нужно указать [B]вне цикла[/B], тогда весь блок цикла помещается в скобки. [code=batch]::Подсчет кол-ва файлов *.txt cmd /c "(for %a in (*.txt) do set /A n+=1)& Echo !n!"[/CODE] Если нужно выполнить несколько команд [B]в цикле[/B], обрамляем их скобками после ключевого слова do: [code=batch]cmd /c "for %a in (*.txt) do (set /A n+=1& Echo !n!)"[/CODE] В однострочной команде переменная сразу не изменяет значения. Получить его можно, влючив "отложенное расширение переменных", а переменную окружив знаками (!): [code=batch]cmd /c "SetLocal EnableDelayedExpansion& Set /A n= 1 + 1& Echo !n!"[/CODE] чтобы не писать такую длинную команду добавьте к CMD ключ /V:ON [B]обязательно перед[/B] ключем /C. Все, что после него считается выполняемыми командами. [code=batch]cmd /v:on /c "Set /A n= 1 + 1& Echo !n!"[/CODE] [COLOR=White].[/COLOR] [COLOR=Green][B]Построение кавычек внутри переменных других ЯП[/B][/COLOR] Кавычка (") - является специальным (служебным) символом для языка Visual Basic, и если в реестре, или в языках C++, C# ... для задания кавычки (") как значение переменной нужно указать экран в виде бекслеша (\) [csharp=-1]st = "\""[/csharp] в VB кавычка удваивается. [B]Есть 2 способа присвоения значений с кавычкой переменной:[/B] 1) Удвоение кавычки [code=vbnet]Shell = "cmd /c ""copy ""c:\my folder\a.txt"" ""c:\my folder\b.txt"""""[/CODE] 2) Через функцию Chr(34), которая возвращает символ под номером 34 ASCII-таблицы кодов ("). В VB результат выполнения функции и строковой тип данных может конкатенироваться знаком амперсанд (&). [code=vbnet]Shell = "cmd /c " & Chr(34) & "copy " & Chr(34) & "c:\my folder\a.txt" & Chr(34) & " " & Chr(34) & "c:\my folder\b.txt" & string(2, Chr(34))[/CODE] Но я предпочитаю вариант № 1. [B]Общий принцип разбора чужих запросов с кавычками таков:[/B] Вариант 1) Автоматически. Поставьте [B][COLOR=Magenta]Stop[/COLOR][/B] после команды присвоения переменной сложного запроса. выполните ?variable {ENTER} в окне Immediate (Вид - окно неотложного (View - Immediate (Ctrl+G))) [spoiler="Увидим результат"][ATTACH=full]14572[/ATTACH] [/spoiler] Вариант 2) Вручную. Кавычка в CMD - это двойная кавычка здесь в переменной ""), т.е. если видите запись вида: [code=vbnet]param = """ """[/CODE] Чтобы "расшифровать", отбрасываете визуально левую и правую кавычку, остальные парные кавычки меняете на одиночные и получаете то, что увидит командная строка: [code=batch]" "[/CODE] Также в реестре, C++, C# ... [B][COLOR=green]спецсимволом является сам знак бекслеш (\)[/COLOR][/B], который разделяет папки, путь к файлу. Здесь приняты 2 способа: 1) Удвоение бекслеша (\\) 2) Замена бекслеша (\) на обычный слеш (/) [B]Альтернативой[/B] для ЯП при использовании Shell является [B][COLOR=seagreen]выгрузка кода в несколько строк во внешний файл[/COLOR][/B]. Запуск его отдельно. При этом такой код может быть заранее: 1) записан в переменную по указанным выше правилам. [spoiler=Выгрузка кода во внешний файл] Код от [B]INV.DS[/B] [code=vbnet] 'Запись: 'Для записи текста служит функция Print(и Write) Open "c:\1.txt" For Append As #1 'Открываем файл для добавления записи, с номером канала Print #1, "Твой ТЕКСТ"' Записываем в файл 1.txt текст Close #1 'Закрываем файл 'Есть еще функция для определения свободного канала - FreeFile. Например: f = FreeFile 'Возвращает номер свободного канала Open "c:\1.txt" For Append As f 'Открываем файл для добавления записи Print #f, "Твой ТЕКСТ"'Записываем в файл 1.txt текст Close #f 'Закрываем файл 'Чтение: 'Считать данные из файла сложнее чем записать. Есть два способа чтения данных из файла. Первый: f = FreeFile Open "c:\1.txt" For Input As f' Открываем файл 1.txt для чтения Text1.Text = Input(LOF(f), f) 'Считываем текст из открытого файла в текстовое поле(Оператор LOF(Len Of File) определяет длину файла) Close f 'Второй: Dim txt as String Open "c:\1.txt" For Input As #1' Открываем файл 1.txt для чтения Do While Not EOF(1) ' Функция EOF(End Of File) проверяет, достигнут ли конец файла Line Input #1, txt ' Читаем строку данных Text1.Text = txt Loop Close #1[/CODE] [/spoiler]2) подключен к проекту в виде файла Custom Resource [Spoiler=VB6. Как добавить ресурс в EXE] Руководство от [B]Alex77755[/B] [ATTACH=full]14567[/ATTACH] [ATTACH=full]14568[/ATTACH] [ATTACH=full]14569[/ATTACH] [ATTACH=full]14570[/ATTACH] [ATTACH=full]14571[/ATTACH] [/spoiler]3) Присоединён в конец уже скомпилированного EXE-файла в открытом виде [spoiler] Код VB6 от [B]Catstail[/B] Вот комментированный код запуска файла, хранящегося в теле другого файла: [code=vbnet] Private Sub Command1_Click() '::: Определяем домашнюю директорию HomeDir$ = App.Path '::: Берем свободный номер файла fi% = FreeFile '::: Открываем сами себя на чтение в двоичном доступе Open HomeDir$ + "\" + App.EXEName + ".exe" For Binary Access Read As #fi% '::: Определяем собственную длину LF& = LOF(fi%) '::: Позиционируем файловый указатель на начало последних '::: 4-x байтов EXE Seek #fi%, LF& - 3 '::: Читаем длину тела запускаемого файла Get #fi%, , Offset& '::: Позиционируем файловый указатель на начало '::: тела запускаемого файла Seek #fi%, LF& - Offset& - 3 '::: Создаем буфер для тела запускаемого файла Buf$ = Space$(Offset&) '::: Читаем тело Get #fi%, , Buf$ '::: Закрываем входной файл Close #fi% '::: Берем свободный номер файла fo% = FreeFile '::: Открываем в тек. директории файл с каким-либо именем Open HomeDir$ + "\notepad.sss" For Binary Access Write As #fo% '::: Сбрасываем в файл содержимое Put #fo%, , Buf$ '::: Закрываем Close #fo% '::: Скрываем форму Me.Hide '::: Запускаем... и ждем завершения Processn.ExecPrg HomeDir$ + "\notepad.sss", "", RC%, vbNormalFocus '::: Дождались - покажем форму Me.Show '::: Удалим запускаемый файл Kill HomeDir$ + "\notepad.sss" '::: Покажем код завершения MsgBox "RC=" + CStr(RC%) End Sub [/CODE] А вот комментированный код exe-мэйкера: [code=vbnet] Sub Main() '::: Домашняя директория HomeDir$ = App.Path '::: Командная строка CMD$ = Command$ '::: положение пробела в ком. строке k% = InStr(CMD$, " ") '::: нет пробела - ошибка If k% = 0 Then MsgBox "Запуск: maker Главный Запускаемый" Exit Sub End If '::: первый параметр - имя главного файла master$ = Left$(CMD$, k% - 1) '::: второй параметр - имя запускаемого из slave$ = Mid$(CMD$, k% + 1) '::: Свободный номер файла fi% = FreeFile '::: Открываем главный (для чтения и записи!) Open HomeDir$ + "\" + master$ For Binary Access Read Write As #fi% '::: Получаем длину LFM& = LOF(fi%) '::: Свободный номер файла ffi% = FreeFile '::: открываем подчиненный (только для чтения) Open HomeDir$ + "\" + slave$ For Binary Access Read As #ffi% '::: Получаем длину LFS& = LOF(ffi%) '::: создаем буфер для запускаемого файла BufS$ = Space$(LFS&) '::: Читаем весь запускаемый файл в буфер Get #ffi%, , BufS$ '::: Позиционируем главный файл в конец Seek #fi%, LFM& + 1 '::: Выводим буфер Put #fi%, , BufS$ '::: выводим длину (чтобы главный мог узнать, сколько байтов от конца нужно взять) Put #fi%, , LFS& '::: Все закрываем Close '::: OK! MsgBox "OK!" End Sub [/CODE] [/spoiler] [B]Некоторые примеры:[/B] 1) Рекурсивный подсчет кол-ва файлов, заданных маской [spoiler] [code=vbnet]Sub CMD_Seek_Recursive() Dim RetCode, Query As String, StartFolder As String, SeekFile As String, Flags As String Dim isRecursive As Boolean Dim inclSystem As Boolean Dim inclHidden As Boolean Dim inclReadOnly As Boolean 'Папка, начиная с которой ведется поиск StartFolder = "l:\bash\test" 'Имя искомого файла (допускается подстановочный знак *) SeekFile = "*.txt" 'Options 'Включить рекурсию isRecursive = True 'Включить в поиск системные, скрытые файлы, только для чтения inclSystem = True inclHidden = True inclReadOnly = True Flags = IIf(isRecursive, "/s", "") + "/a:-D" + _ IIf(inclSystem, "", "-S") + IIf(inclHidden, "", "-H") + IIf(inclReadOnly, "", "-R") Query = "cmd.exe /Q /V:on /C ""(for /f ""delims="" %x in ('dir /b " & Flags & " " & _ """" & StartFolder & "\" & SeekFile & """') do (set /a n+=1))& Exit !n!""" RetCode = CreateObject("WScript.Shell").Run(Query, 0, True) Debug.Print "Количество найденных файлов = " & RetCode End Sub[/CODE] И чуть по-меньше буков: [code=vbnet]Sub CheckCount() Debug.Print Get_Count_Files("l:\bash\test", "*.txt") End Sub 'Выдает кол-во файлов SeekFile в папке StartFolder рекурсивно без учета скрытых файлов Function Get_Count_Files(StartFolder As String, SeekFile As String) As Long Get_Count_Files = CreateObject("WScript.Shell").Run("cmd /V:on /C ""(for /R """ & _ StartFolder & """ %x in (""" & SeekFile & """) do set /a n+=1)& Exit !n!""", 0, True) End Function[/CODE] [/spoiler] 2) Еще в VB можно получить код возврата, сгенерированного командами CMD или вручную через Exit [spoiler] Метод от [B]Казанский[/B] [B][COLOR=Blue]Получение ErrorLevel из команды CMD в переменную VBS-скрипта[/COLOR][/B] (на примере команды сравнения файлов) [code=vbnet]Function FileCompare(path1, path2) 'возвращает результат двоичного сравнения двух файлов 'с помощью системной утилиты fc.exe. Возвращаемое значение: '0 - файлы одинаковы; '1 - файлы различаются; '2 - файл не найден FileCompare = CreateObject("wscript.shell").Run( _ "cmd /c fc /b """ & path1 & """ """ & path2 & """", 0, True) End Function [/CODE] Комментарий [B]Dragokas:[/B] Добавлю от себя: чтобы симитировать свой произвольный код возврата, достаточно указать команду Exit <code> Например, [code=vbnet]'Двоичный сдвиг 0110(6) -> 0011(3) FileCompare = CreateObject("wscript.shell").Run( _ "cmd /v:on /c set /A x=6"">>""1& exit !x!", 0, True)[/CODE] [/spoiler] [/QUOTE]
Вставить цитаты...
Проверка
Ответить
Форумы
Форум программистов
Visual Basic 6 / Сценарии VBScript, JScript
Изучение основ языка
Принцип составления однострочных команд для метода Shell
Сверху
Снизу