«Полезняшки» или «Реестр Windows как платформа»

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

    Приоритеты


    Давным-давно, когда я переходил с ХР на Семерку, одним из важных преимуществ новой системы я считал введение приоритетов на ввод-вывод и на пейджинг, а не только на процессор. Однако сейчас у нас Десятка на дворе, а удобных штатных средств управления этими приоритетами так и не появилось.
    Как я с удивлением обнаруживаю, большинство пользователей вообще не в курсе о такой замечательной возможности. Их удовлетворяет опция в Task Manager по смене текущего приоритета CPU для уже запущенного процесса (и то только если им это будет позволено). А ситуацию, когда даже выставленный в LOW фоновый процесс своим дисковым обменом или свопингом мешает работать более приоритетным задачам, считают неизбежным злом.

    Некоторые, устав от обращения к Task Manager при каждом запуске, вставляют в ярлыки запуска критичных программ перед самим объектом что-то вроде

    cmd /c start /realtime

    Это позволяет запустить что-то с приоритетом HIGH (а не realtime, как они думают), но никак не затрагивает проблему с приоритетом ввода-вывода. Кроме того, ряд приложений используют файл-запускальщик, который, в свою очередь, запускает основную программу. А она в таком варианте будет запущена с приоритетом по умолчанию, и лишь уже не нужный запускальщик будет красоваться в Task Manager с приоритетом HIGH.

    Решением проблемы является создание веток в «Image File Execution Options» в реестре, но руками это делать достаточно утомительно.

    Конечно, есть ряд сторонних приложений, которые позволят вам прописать правильные ветки в реестре для нужной программы, но я специально упомянул в первом абзаце слово «штатных»: зачастую это нужно делать на машине, на которой запрещена установка сторонних экзешников, отключены сменные носители, и затруднено получение (как из интернета, так и по почте) любых исполняемых файлов, пакетов, архивов, BAT, CMD и даже REG-файлов. В особо серьезных случаях контролируется реальное содержимое файла на предмет смены типа или внедрение в документ-контейнер вложения недозволенного типа.

    Итак, намаявшись с реестром, я поставил себе задачу написать утилитку, которая позволяет менять базовый приоритет запуска программы как для CPU, так и для IO и Paging, и при этом:

    • использует только штатные средства, присутствующие в дефолтной инсталляции windows.
    • избавляет от необходимости вписывать имя файла (например, активируясь из его контекстного меню)
    • избавляет от необходимости во введении пароля администратора в командной строке или в предварительном открытии сессии под администратором (единственно, что допустимо – всплывающее окно UAC)
    • (необязательно) не оставляет никаких постоянных файлов на диске (дабы не нервировать сотрудников Первого отдела)
    • (необязательно) поддерживает деинсталляцию
    • (главное) может быть получена, как текст (по почте или с web-страницы), а не файл.

    Последнее требование важно не только в плане доставки. Это универсальный способ показать пользователю, что утилита не содержит закладок или нежелательного функционала. Заодно и выполнение одного из требований GPL – предоставления исходного кода.

    Изложенные требования определили выбор, что это должен быть скриптовый язык, последующие исследования показали, что даже к PowerShell прибегать не нужно, достаточно будет обычного синтаксиса CMD и VBS, затем попробовал уместить одно действие в одну строку, а не в bat-файл, а далее, так как в любом случае требовалась запись в реестр, родилась мысль уместить все в самом реестре, тем самым выполнив условие по отсутствию файлов.

    В итоге получилась утилитка, которая выглядит, как выпадающее подменю в свойствах исполняемых файлов:

    image

    А вот она сама:

    Windows Registry Editor Version 5.00 
    
    ;Copyright 2016 Trottle 
    ;This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3. 
    ;This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
    ;See <http://www.gnu.org/licenses/> for more details. 
    
    [-HKEY_CLASSES_ROOT\exefile\shell\Bpc] 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc] 
    "HasLUAShield"="" 
    "MUIVerb"="Set base priority" 
    "subcommands"=""
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\01low] 
    "MUIVerb"="Idle CPU, lowest IO, low paging" 
    "Icon"="comres.dll,9" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\01low\command] 
    @="cmd /q /c echo Windows Registry Editor Version 5.00>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & for /f \"delims=<\" %%i in (\"%1\") do echo [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%%~nxi\\PerfOptions]>>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"CpuPriorityClass\"=dword:00000001>>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"IoPriority\"=dword:00000000>>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"PagePriority\"=dword:00000001>>%%TEMP%%\\pr.reg & regedit /s %%TEMP%%\\pr.reg & del %%TEMP%%\\pr.reg & msg * %~ni priority is set to IDLE" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\02below] 
    "MUIVerb"="Below normal CPU, low IO" 
    "Icon"="comres.dll,12" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\02below\command] 
    @="cmd /q /c echo Windows Registry Editor Version 5.00>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & for /f \"delims=<\" %%i in (\"%1\") do echo [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%%~nxi\\PerfOptions]>>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"CpuPriorityClass\"=dword:00000005>>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"IoPriority\"=dword:00000001>>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"PagePriority\"=->>%%TEMP%%\\pr.reg & regedit /s %%TEMP%%\\pr.reg & del %%TEMP%%\\pr.reg & msg * %~ni priority is set to BELOW NORMAL" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\03above] 
    "Icon"="comres.dll,8" 
    "MUIVerb"="Above normal CPU" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\03above\command] 
    @="cmd /q /c echo Windows Registry Editor Version 5.00>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & for /f \"delims=<\" %%i in (\"%1\") do echo [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%%~nxi\\PerfOptions]>>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"CpuPriorityClass\"=dword:00000006>>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"IoPriority\"=->>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"PagePriority\"=->>%%TEMP%%\\pr.reg & regedit /s %%TEMP%%\\pr.reg & del %%TEMP%%\\pr.reg & msg * %~ni priority is set to ABOVE NORMAL" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\04high] 
    "MUIVerb"="High CPU" 
    "Icon"="comres.dll,16" 
    "CommandFlags"=dword:00000040
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\04high\command] 
    @="cmd /q /c echo Windows Registry Editor Version 5.00>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & for /f \"delims=<\" %%i in (\"%1\") do echo [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%%~nxi\\PerfOptions]>>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"CpuPriorityClass\"=dword:00000003>>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"IoPriority\"=->>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & echo \"PagePriority\"=->>%%TEMP%%\\pr.reg & regedit /s %%TEMP%%\\pr.reg & del %%TEMP%%\\pr.reg & msg * %~ni priority is set to HIGH" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\06ask] 
    "MUIVerb"="Show current priorities" 
    "Icon"="shell32.dll,23" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\06ask\command] 
    @="cmd /q /c for /f \"delims=<\" %%i in (\"%1\") do reg query \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%%~nxi\\PerfOptions\" /s | msg *" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\07default] 
    "MUIVerb"="Restore to default" 
    "Icon"="comres.dll,4" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\Bpc\shell\07default\command] 
    @="cmd /q /c echo Windows Registry Editor Version 5.00>%%TEMP%%\\pr.reg & echo.>>%%TEMP%%\\pr.reg & for /f \"delims=<\" %%i in (\"%1\") do echo [-HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%%~nxi\\PerfOptions]>>%%TEMP%%\\pr.reg & regedit /s %%TEMP%%\\pr.reg & del %%TEMP%%\\pr.reg & msg * %~ni priority is restored to default" 
    
    ; If you do not want to have uninstaller you can skip next part: 
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\BpcSubMenu] 
    "DisplayName"="'Set base priority' submenu" 
    "DisplayIcon"="imageres.dll,73" 
    "UninstallString"="cmd /q /c echo Windows Registry Editor Version 5.00>%TEMP%\\pr.reg & echo.>>%TEMP%\\pr.reg & echo [-HKEY_CLASSES_ROOT\\exefile\\shell\\Bpc]>>%TEMP%\\pr.reg & echo.>>%TEMP%\\pr.reg & echo [-HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\BpcSubMenu]>>%TEMP%\\pr.reg & regedit /s %TEMP%\\pr.reg & del %TEMP%\\pr.reg" 
    "DisplayVersion"="1.1" 
    "URLInfoAbout"="http://habrahabr.ru/post/317802/" 
    "NoModify"=dword:00000001 
    "NoRepair"=dword:00000001

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

    При этом, правда, стоит учитывать две вещи:

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

    2. Windоws почему-то показывает подменю не только на самих.ЕХЕ, но и на их ярлыках, но при этом не вызывает на последних пункты подменю.

    Также вы, должно быть, заметили, что:

    — во-первых, нет приоритета Realtime,
    — во вторых, все приоритеты, кроме CPU, идут только в сторону уменьшения
    — в третьих, приоритет Paging ставится чуть выше, чем приоритет IO.

    Это соответствует рекомендациям Microsoft по работе с приоритезацией:

    — уменьшать у ненужного, а не увеличивать у нужного;
    — свопинг важнее работы с файлами;
    — не работать с Realtime («честный» риалтайм действительно может быть опасен для стабильности всей системы, поэтому через реестр ни его, ни высокий приоритет IO не выставить).

    Брандмауэр


    Между первой и второй промежуток небольшой – решил таким же образом упростить работу со штатным брандмауэром. Многим он хорош, но не удобством обращения с ним. В данном случае решил ускорить создание разрешений или запрещений на программу. (Считаю возможность привязывать правила к программам главным преимуществом внутреннего брандмауэра перед внешним.) Я использую брандмауэр в режиме блокировки исходящих соединений по умолчанию, поэтому добавлять новую программу, как правило, приходится часто.

    Получилось такое:

    image

    и текст:

    Windows Registry Editor Version 5.00 
    
    ;Copyright 2016 Trottle 
    ;This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3. 
    ;This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
    ;See <http://www.gnu.org/licenses/> for more details. 
    
    [-HKEY_CLASSES_ROOT\exefile\shell\FWc] 
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc] 
    "MUIVerb"="Set firewall rules" 
    "Icon"="imageres.dll,102" 
    "subcommands"=""
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc\shell\01] 
    "MUIVerb"="block inbound" 
    "Icon"="imageres.dll,100" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc\shell\01\command] 
    @="cmd /q /c echo CreateObject(\"Shell.Application\").ShellExecute \"cmd\", \"/q /c chcp 1251 & netsh advfirewall firewall add rule name=\"\"%1\"\" dir=in action=block program=\"\"%1\"\" enable=yes | msg * \", \"\", \"runas\" > %%temp%%\\ev.vbs & cscript %%temp%%\\ev.vbs & del %%temp%%\\ev.vbs" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc\shell\02] 
    "MUIVerb"="allow inbound" 
    "Icon"="imageres.dll,101" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc\shell\02\command] 
    @="cmd /q /c echo CreateObject(\"Shell.Application\").ShellExecute \"cmd\", \"/q /c chcp 1251 & netsh advfirewall firewall add rule name=\"\"%1\"\" dir=in action=allow program=\"\"%1\"\" enable=yes | msg * \", \"\", \"runas\" > %%temp%%\\ev.vbs & cscript %%temp%%\\ev.vbs & del %%temp%%\\ev.vbs" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc\shell\03] 
    "Icon"="imageres.dll,100" 
    "MUIVerb"="block outbound" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc\shell\03\command] 
    @="cmd /q /c echo CreateObject(\"Shell.Application\").ShellExecute \"cmd\", \"/q /c chcp 1251 & netsh advfirewall firewall add rule name=\"\"%1\"\" dir=out action=block program=\"\"%1\"\" enable=yes | msg * \", \"\", \"runas\" > %%temp%%\\ev.vbs & cscript %%temp%%\\ev.vbs & del %%temp%%\\ev.vbs" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc\shell\04] 
    "MUIVerb"="allow outbound" 
    "Icon"="imageres.dll,101" 
    "CommandFlags"=dword:00000040
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc\shell\04\command] 
    @="cmd /q /c echo CreateObject(\"Shell.Application\").ShellExecute \"cmd\", \"/q /c chcp 1251 & netsh advfirewall firewall add rule name=\"\"%1\"\" dir=out action=allow program=\"\"%1\"\" enable=yes | msg * \", \"\", \"runas\" > %%temp%%\\ev.vbs & cscript %%temp%%\\ev.vbs & del %%temp%%\\ev.vbs" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc\shell\06] 
    "MUIVerb"="Show firewall panel" 
    "Icon"="imageres.dll,109" 
    
    [HKEY_CLASSES_ROOT\exefile\shell\FWc\shell\06\command] 
    @="mmc.exe wf.msc" 
    
    ; If you do not want to have uninstaller you can skip next part: 
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\FWcSubMenu] 
    "DisplayName"="'Set firewall rules' submenu" 
    "DisplayIcon"="imageres.dll,102" 
    "UninstallString"="cmd /q /c echo Windows Registry Editor Version 5.00>%TEMP%\\pr.reg & echo.>>%TEMP%\\pr.reg & echo [-HKEY_CLASSES_ROOT\\exefile\\shell\\FWc]>>%TEMP%\\pr.reg & echo.>>%TEMP%\\pr.reg & echo [-HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\FWcSubMenu]>>%TEMP%\\pr.reg & regedit /s %TEMP%\\pr.reg & del %TEMP%\\pr.reg" 
    "DisplayVersion"="1.1" 
    "URLInfoAbout"="http://habrahabr.ru/post/317802/" 
    "NoModify"=dword:00000001 
    "NoRepair"=dword:00000001 

    Замечу, что, в отличие от первой утилитки, здесь клик на одном пункте не отменяет другие, т.е. создание запрещающего правила не стирает разрешающее, и наоборот. Сделано это на случай, когда создается несколько правил на одну программу и в дальнейшем каждое уточняется (по портам, адресам, режимам, и т.д.). Таким образом, если кликнуть и на «allow», и на «block», будет создано 2 правила, а сетевой доступ программе будет закрыт (запрещающие правила имеют приоритет перед разрешающими).

    Деинсталляция для обеих утилит штатная – заходим в «Программы и компоненты» и удаляем:

    image

    P.S. Друзья, благодаря вашим отзывам улучшил отображение подменю в Win10, исходники обновлены до версии 1.1
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 35

      0
      Забавно. Спасибо
        0

        Спасибо. Пригодится. Есть ли возможность аналогичным удобным путем ограничить сетевой траффик ?

          0
          не совсем понял, ограничить в смысле «не перекрыть, а задать полосу пропускания»? К сожалению, не занимался этим, хотя шейпинг трафика — тема действительно интересная.
          0
          Не хватает записей в «Установка и удаление» и деинсталлятора по той же методике.
            0
            Судя по фразе «Установка и удаление», а не «Программы и компоненты», вы всё ещё используете ХР. Жаль, нет её сейчас под рукой, но я рассчитывал, что первая утилитка будет и под ней работать, посему обошелся без PowerShell (правда, пользы от нее там не так много — в ХР только приоритет CPU поддерживается). А вот вторая использует новый синтаксис netsh и в ХР не заработает…
            +10

            Это прекрасно. Вы используете винду как линукс. Поясню свою мысль. На линуксе можно по-быстрому нахакать какой-нибудь шел-скрипт, который будет генерить скрипт на седе, который будет генерить какой-нибудь юнит-файл для 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 .". А вот что делать дальше, куда ставить и главное, зачем, не понятно. Куда принято ставить библиотеки в винде и как их потом использовать?

            По всем этим вопросам, я, как мне кажется, хорошо разбираюсь, если дело касается линукса. Могу написать на эти темы статью (статьи), если интересно

              +1
              Неужели для консольной программы писать графический инсталлятор со всякими Далее-Далее-Готово?

              Это не относится к только консольным программам, но можно взять генератор инсталляторов (InnoSetup etc) и написать только небольшой конфиг к нему (есть даже графические утилиты для "написания" таких конфигов). Полученный инсталлятор, как правило, можно запустить и в "тихом" режиме.

                +1

                В винде шаблоны раскрываются аналогично интерпретатором (в большинстве случаев). Но надо всё закавычивать (например, dir "", чтобы вывести каталог с пробелом)


                Встроенные команды надо передавать интерпретатору, то есть cmd /c "dir c:\"


                Есть проблема манипуляции с аргументами: %1, %2,… и % для доступа ко всем аргументам. Но в большинстве случаев % бесполезен. Нет такой возможности как ${@:n:m}. И кавычки снова надо "закавычивать" или "искейпить".


                На отальные вопросы будет ответ — как бог на душу положит. Кто-то работает с реестром, кто-то пишет ini-файлы и разбирает их, кто-то пишет конфиг-файлы по типу самого скрипта (аналогия, sourced фвйлы в юникс).

                  0

                  имелось в виду
                  например, dir "* *", чтобы вывести каталог с пробелом
                  %1, %2,… и %* для доступа ко всем аргументам. Но в большинстве случаев %* бесполезен

                  0
                  Тут уже откликнулись на ваш пост, так что добавлю немного: действительно, с разделителями (да и не только) единообразия нет:
                  — во-первых, строки команд в реестре — это не полноценная shell-строка, а именно «программа и её аргументы», т.е. если вы зададите встроенную команду (echo, start, set и т.д.), вас не поймут. Если используете %переменную%, вас не поймут, если зададите команду & команду, вас не поймут. Поэтому в тексте вы часто видите «cmd /c» — это получение «полноценной» командной строки
                  — набор параметров, передаваемых в программу, в реестре свой — %0=%1,%l,%w,%i,…
                  — обработка разделителей -вообще мрак: вы видите в примерах, что \ и " нужно предварять \, < и > — оставлять как есть, а % где-то нужно дублировать, а где-то нет.
                    0
                    Интересно, давай статью!!!
                      –2

                      Мне расхотелось писать статью, в следующей жизни напишу :)

                      0
                      Все не знаю, но попробую ответить.
                      • Звездочки не раскрываются, этим должна заниматься программа. Например, 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».
                        0
                        Логи можно вполне прилично складывать в EventLog
                        –1

                        Спасибо за ответы. В общем, больше не надо, я дальше как-нибудь сам разберусь. Разве что ссылки не помешают

                        0
                        Прикольный хак

                        Для автоматического повышения приоритета юзаю AnVir, не помогало, все съедал своп, но как психотерапия сойдет.

                        Утилита не показывает приоритет для файлов, к которым не применялась — запускается консоль и закрывается без показа сообщения.

                          0

                          "UninstallString"="cmd /q /c echo Windows Registry Editor Version 5.00>%TEMP%\\pr.reg ...


                          Не пишите так больше.


                          1. можно допустить ошибку и все пойдет совсем не так.
                          2. можно писать во временные файлы, потом запускать regedit /s, но для этого давно есть команды reg add / reg delete, Пользуйтесь ими
                          3. Всё что больше 2-3 слов пишите в скрипт. То есть не вызов кучи cmd /c с параметрами, а один простой пакетный скрипт. И короче, и понятнее, и параметры можно передавать.
                            0
                            1. Errare humanum est, что поделаешь… Это может случиться где угодно.
                            2. Вы не совсем поняли — в двух утилитках я использую разные способы повышения привилегий. Если бы я использовал REG для внесения в реестр, мне пришлось бы делать VBS-ную обвязку, чтобы команда сработала. А у regedit очень удобный «побочный эффект» — он сам рисует окно UAC
                            3. Поначалу это и было скриптом, но потом я понял, что смогу выполнить и 4-й пункт задачи.
                          • UFO just landed and posted this here
                              0
                              не столько для тяжелого, сколько для критичного к задержкам (например, для VR здорово помогает убрать отдельные рывки — а это там самое неприятное), а они возникают чаще по причине ожидания диска, а не CPU. Но все в основном крутят на подъем приоритета, хотя лучше — наоборот снижать у фоновых процессов.
                              0

                              Спасибо, очень понравился и подход, и исполнение.

                                0
                                Что-то у меня вместо разделяющей полосы отображается надпись «05delim».
                                  0
                                  Это интересно… У меня на всех машинах — если пункт подменю без MUIVerb, то выводится горизонтальная черта. (в отличие от пунктов основного меню — там если нет MUIVerb, берется название раздела.) Какая у вас версия Windows?
                                    0
                                    Windows 10 1607 x64
                                      0
                                      У меня так же «05delim»
                                      Windows 10 Pro 1607 x64

                                      image
                                        0
                                        OK, изменил способ задания разделителя, исходники обновлены до версии 1.1 (можно ставить поверх предыдущей, без анинсталла)
                                          0
                                          То есть вы убрали разделитель, а не изменили способ его создания (разделитель исчез)?
                                            0
                                            Теперь разделителя вообще нету)

                                            image
                                      0
                                      Прощай Диспетчер задач (на время)
                                        0
                                        Почему «прощай»? Как раз в нем — сортируем по максимальному CPU, «Прочитано-» или «Записано байт», далее по right click «Открыть место хранения файла» и снижаем ему приоритет.
                                        Единственно, осторожней с svchost.exe — это понизит приоритет почти всех служб (впрочем, если до below normal, то работает нормально)
                                        +4
                                        Респект автору за Uninstall. Не остановился на полпути :-)
                                          +1
                                          Спасибо за информацию об аналоге ionice под Windows.
                                          Но вернёмся к открытому более десяти лет вопросу:
                                          Как ограничить в ресурсах пользователя сервера терминалов:
                                          Пусть есть некий терминальный сервер, на нём — 1С, браузер (клиент-банк).
                                          Пользователь может (а раз может — значит обязательно сделает) запустить криво написанный отчёт, отжирающий память и ядра CPU. Также пользователь может запустить неограниченное число (очень нужных вот прямщас) вкладок браузера.
                                          Можно ли ограничить память на процесс?
                                          Оптимальным было бы также «шейпить» CPU и дисковую подсистему. Не выставлять приоритет, а именно шейпить.

                                          Возможно ли это в принципе на платформе Windows?
                                            +1
                                            Возможно. Оснастка называется «Политики выделения ресурсов».
                                            +1
                                            «Но вернёмся к открытому более десяти лет вопросу»
                                            не гуглить с 2009 года? а вы профессионал :)
                                            wsrm
                                            блин, веткой промахнулся
                                              0
                                              Спасибо, прекрасная идея и интересная реализация
                                              Обратите внимание на ключ 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"

                                              Only users with full accounts can post comments. Log in, please.