Комментарии 35
Спасибо. Пригодится. Есть ли возможность аналогичным удобным путем ограничить сетевой траффик ?
Это прекрасно. Вы используете винду как линукс. Поясню свою мысль. На линуксе можно по-быстрому нахакать какой-нибудь шел-скрипт, который будет генерить скрипт на седе, который будет генерить какой-нибудь юнит-файл для systemd, который ещё чё-нибудь куда-нибудь пропишет и так далее и тому подобное. Теперь выясняется, что в винде так тоже можно. В связи с этим у меня к вам как к эксперту по использованию винды в качестве линукса (ну и к другим хабравчанам), есть пара вопросов. Ответьте, если не сложно. Ну или ссылки дайте или направление хотя бы.
- В линуксе при написании скриптов на баше, программ на си, всемозможных sed'овых регексов и так далее нужно знать, что и когда эскейпить, помещать в кавычки и так далее. Скажем, вот так писать нельзя: find -name *.txt, надо так: find -name '*.txt', а вот у rm, напротив, надо так: rm *.txt. Расскажите, как с этим в винде. Как работают все эти кавычки в cmd? Скажем, в баше баш сам звёздочки раскрывает. А в винде что?
- Тесно связанный с предыдущим вопрос. В линуксе есть exec-команды и есть shell-команды (термины мои, но сами понятия, стоящие за ними, разумеется, не мои). Exec-команда — это команда, предназначенная непосредственно для исполнения ядром (т. е. для передачи системным вызовам семейства exec). Shell-команда — это команда, которая будет обработана шелом. Скажем, chroot воспринимает свои аргументы, начиная со второго, как exec-команду, т. е. сразу передаёт её ядру. Поэтому, скажем, нельзя написать chroot / cd. Т. к. cd — это внутренная команда bash'а, здесь так не прокатит. А вот, скажем, ssh принимает в качестве аргументов, начиная со второго, shell-команду. Так что писать ssh user@host cd можно (хотя ничего эта команда не даст), да и вообще вторым аргументом в ssh можно запихнуть любую башевую команду, пускай даже с ветвлениями и прочее. С chroot такое не прокатит. Как со всем этим обстоят дела в винде? Если запустить команду "cmd /q /c ..." (вижу у вас там в посте такую) каким конкретно преобразованиям будет подвергнута команда, переданная в cmd (ну там, убирания кавычек и т. д.)? Какими функциями WinAPI запускаются команды для запуска сразу ядром и какими — шелом? И вообще, в линуксе shell-команда — это строка, а exec-команда — это массив строк. А в винде? Как формируется argv[], который получает программа на си?
- Каковы, скажем так, "правила поведения" для виндовых программ (всех, консольных и графических)? Как им себя вести, чтобы не мешать другим программам? Где, скажем, хранить настройки и прочее-прочее? В линуксах я знаю, конфиги — в /etc, логи — в /var/log и так далее. В линуксе есть хороший гайд по требования к пакетам свободного ПО: https://wiki.debian.org/UpstreamGuide. На многие мелкие темы можно найти кучу подробных ответов, скажем, где хранить временные файлы: http://0pointer.net/blog/projects/tmp.html .
- А существуют ли специфичные "правила поведения" для консольных программ? Как лучше всего распространять консольные программы? Неужели для консольной программы писать графический инсталлятор со всякими Далее-Далее-Готово?
- Как распространять библиотеки на си? Чтобы пользователь после установки мог сразу их заюзать в своём visual studio. Куда хедеры класть? Вот у меня есть библиотека на си: http://github.com/safinaskar/libsh. Поддерживает линукс и винду. На линуксе собирается и ставится при помощи "cmake. && make && make install". На винде собирается при помощи "cmake. && cmake --build .". А вот что делать дальше, куда ставить и главное, зачем, не понятно. Куда принято ставить библиотеки в винде и как их потом использовать?
По всем этим вопросам, я, как мне кажется, хорошо разбираюсь, если дело касается линукса. Могу написать на эти темы статью (статьи), если интересно
Неужели для консольной программы писать графический инсталлятор со всякими Далее-Далее-Готово?
Это не относится к только консольным программам, но можно взять генератор инсталляторов (InnoSetup etc) и написать только небольшой конфиг к нему (есть даже графические утилиты для "написания" таких конфигов). Полученный инсталлятор, как правило, можно запустить и в "тихом" режиме.
В винде шаблоны раскрываются аналогично интерпретатором (в большинстве случаев). Но надо всё закавычивать (например, dir "", чтобы вывести каталог с пробелом)
Встроенные команды надо передавать интерпретатору, то есть cmd /c "dir c:\"
Есть проблема манипуляции с аргументами: %1, %2,… и % для доступа ко всем аргументам. Но в большинстве случаев % бесполезен. Нет такой возможности как ${@:n:m}. И кавычки снова надо "закавычивать" или "искейпить".
На отальные вопросы будет ответ — как бог на душу положит. Кто-то работает с реестром, кто-то пишет ini-файлы и разбирает их, кто-то пишет конфиг-файлы по типу самого скрипта (аналогия, sourced фвйлы в юникс).
— во-первых, строки команд в реестре — это не полноценная shell-строка, а именно «программа и её аргументы», т.е. если вы зададите встроенную команду (echo, start, set и т.д.), вас не поймут. Если используете %переменную%, вас не поймут, если зададите команду & команду, вас не поймут. Поэтому в тексте вы часто видите «cmd /c» — это получение «полноценной» командной строки
— набор параметров, передаваемых в программу, в реестре свой — %0=%1,%l,%w,%i,…
— обработка разделителей -вообще мрак: вы видите в примерах, что \ и " нужно предварять \, < и > — оставлять как есть, а % где-то нужно дублировать, а где-то нет.
- Звездочки не раскрываются, этим должна заниматься программа. Например,
del dir/*
(в linux это rm) удаляет все файлы в директории dir, при этом кавычки вокруг «dir/*» можно ставить, а можно нет. И так в любом случае со звездочкой. Но зато кавычки можно ставить только вокруг всего параметра (например, так можно:del "file.txt"
;"/path to my program/some good program.exe" data.txt
— здесь в кавычки берем путь к исполняемому файлу, так как в нем пробелы). А так нельзя:del "file with spaces".txt
- Чего-то похожего на chroot в Windows я не знаю, но разделения на shell- и exec-команд нет. Разделение только на исполняемые файлы и команды. Например, Вы можете из командной строки выполнить:
C:\Users\user\> dir C:\ /w ... Users Program Files Program Data ... C:\Users\user\> "C:\Program Files\Google\Chrome\chrome.exe" # Chrome запустился
А, скажем, выполнить файлdir C:\ /w
из, скажем, VBS, не получится, зато получитсяchrome.exe
.
cmd /q /c
запускает команду как из шелла, то есть, скажем, пример выше нужно написать так, чтобы он заработал не из командной строки:cmd /q /c "dir C:\ /w"
. Я обернул команду в кавычки. Экранирование — это, внезапно,^
. То есть выполнитьdir "C:\long path"
можно примерно так:cmd /q /c "dir ^"C:\long path^""
Пусть программа лежит в корне, перед выполнением сделалиcd C:\
.argv[]
при выполнении командыC:\exec abc def
будет"C:\exec", "abc", 'def"
. При выполненииexec abc def
будет"exec" "abc" "def"
и т. д. Кавычки остаются.
- Настройки и прочее-прочее принято хранить в «C:\Program Data\Chrome», «C:\Users\user\AppData\Roaming\Chrome», «C:\Users\user\AppData\Local\Chrome» или в реестр. Логи туда же (только в реестр нельзя). Временные файлы в «C:\Users\user\AppData\Local\Temp».
Спасибо за ответы. В общем, больше не надо, я дальше как-нибудь сам разберусь. Разве что ссылки не помешают
"UninstallString"="cmd /q /c echo Windows Registry Editor Version 5.00>%TEMP%\\pr.reg ...
Не пишите так больше.
- можно допустить ошибку и все пойдет совсем не так.
- можно писать во временные файлы, потом запускать regedit /s, но для этого давно есть команды reg add / reg delete, Пользуйтесь ими
- Всё что больше 2-3 слов пишите в скрипт. То есть не вызов кучи cmd /c с параметрами, а один простой пакетный скрипт. И короче, и понятнее, и параметры можно передавать.
2. Вы не совсем поняли — в двух утилитках я использую разные способы повышения привилегий. Если бы я использовал REG для внесения в реестр, мне пришлось бы делать VBS-ную обвязку, чтобы команда сработала. А у regedit очень удобный «побочный эффект» — он сам рисует окно UAC
3. Поначалу это и было скриптом, но потом я понял, что смогу выполнить и 4-й пункт задачи.
Спасибо, очень понравился и подход, и исполнение.
Windows 10 Pro 1607 x64
Единственно, осторожней с svchost.exe — это понизит приоритет почти всех служб (впрочем, если до below normal, то работает нормально)
Но вернёмся к открытому более десяти лет вопросу:
Как ограничить в ресурсах пользователя сервера терминалов:
Пусть есть некий терминальный сервер, на нём — 1С, браузер (клиент-банк).
Пользователь может (а раз может — значит обязательно сделает) запустить криво написанный отчёт, отжирающий память и ядра CPU. Также пользователь может запустить неограниченное число (очень нужных вот прямщас) вкладок браузера.
Можно ли ограничить память на процесс?
Оптимальным было бы также «шейпить» CPU и дисковую подсистему. Не выставлять приоритет, а именно шейпить.
Возможно ли это в принципе на платформе Windows?
не гуглить с 2009 года? а вы профессионал :)
wsrm
блин, веткой промахнулся
Обратите внимание на ключ Extended="" в элементах меню.
При его использовании меню будет появляться только с нажатым shift (как в случае с пунктом «копировать как путь») и стандартное же останется нетронутым.
Согласитесь, несмотря на бесспорную полезность вышеописанного функционала — он требуется не каждый день.
[-HKEY_CLASSES_ROOT\exefile\shell\SCs]
[HKEY_CLASSES_ROOT\exefile\shell\SCs]
"MUIVerb"="Set autorun"
"Icon"="imageres.dll,99"
"subcommands"=""
"Extended"=""
[HKEY_CLASSES_ROOT\exefile\shell\SCs\shell\01]
"MUIVerb"="add to autorun"
"Icon"="imageres.dll,101"
[HKEY_CLASSES_ROOT\exefile\shell\SCs\shell\01\command]
@="cmd /q /c echo CreateObject(\"Shell.Application\").ShellExecute \"cmd\", \"/q /c reg add hkcu\\software\\microsoft\\windows\\currentversion\\run /v %1 /t reg_sz /d %1 /f & echo autorun %1 added | msg * \", \"\", \"runas\" > %%temp%%\\ar.vbs & cscript %%temp%%\\ar.vbs & del %%temp%%\\ar.vbs"
[HKEY_CLASSES_ROOT\exefile\shell\SCs\shell\02]
"MUIVerb"="remove autorun"
"Icon"="imageres.dll,100"
[HKEY_CLASSES_ROOT\exefile\shell\SCs\shell\02\command]
@="cmd /q /c echo CreateObject(\"Shell.Application\").ShellExecute \"cmd\", \"/q /c reg delete hkcu\\software\\microsoft\\windows\\currentversion\\run /v %1 /f & echo autorun %1 deleted | msg * \", \"\", \"runas\" > %%temp%%\\ar.vbs & cscript %%temp%%\\ar.vbs & del %%temp%%\\ar.vbs"
«Полезняшки» или «Реестр Windows как платформа»