Страницы

Поиск по вопросам

Показаны сообщения с ярлыком bat. Показать все сообщения
Показаны сообщения с ярлыком bat. Показать все сообщения

четверг, 9 апреля 2020 г.

Открыть *.html файл во весь экран

#bat

                    
Пишется *.bat-файл для для запуска файла *.html на компьютере пользователя в браузере:

start index.html
exit


Как открывать его во весь экран?
    


Ответы

Ответ 1



start "" "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --kiosk --start-fullscreen -- file://D:/Temp/Supertemp/index.html Проверено на Google Chrome 45.0.2454.101 (Официальная сборка) m (64 бит)

Ответ 2



SendMessage App + WM_KEYDOWN + Virtual-Key Codes Окно браузера определяется по заголовку или по классу (тогда нужна программа типа Spy+). Дальше, с помощью SendMessage окну посылается сообщение WM_KEYDOWN(F11).

воскресенье, 8 марта 2020 г.

Как с помощью bat-файла запустить программу по сети?

#windows #bat


Как с помощью bat-файла запустить программу по сети?

Например, я по сети выполняю команду:

taskkill /s 10.10.10.10 /IM Name.exe

Эта команда завершает процесс Name.exe. Работает. А как снова запустить этот процесс?
 Либо файл exe (расположение файла известно).
    


Ответы

Ответ 1



В составе Sysinternals Suite есть утилита psexec: psexec \\10.10.10.10 <путь_к_программе_на_удаленной_машине> (возможно, вам потребуются опции -u, -p для указания имени пользователя/пароля для подключения к машине)

пятница, 14 февраля 2020 г.

Как через echo вывести в файл слово SERVICE?

#windows #oracle #bat


Пытаюсь силами bat файла создать файл инициализации для БД Oracle.
Минимальный пример моего файла:

@echo off
SET ORACLE_SID=SID1
IF 1==1 (
echo *.dispatchers='(PROTOCOL=TCP) (SERVICE=%ORACLE_SID%2XDB)' >>D:\1.TXT
)


Получаю ошибку:


  (SERVICE was unexpected at this time.


Ругается на слово SERVICE. Как можно заставить работать этот вывод?

Из забавного, если убрать IF, то ошибок нет.

Пробовал экранировать слово символом ^, однако к успеху это не привело
    


Ответы

Ответ 1



Пробовал экранировать слово символом ^, однако к успеху это не привело Экранировать символом ^ нужно закрывающие скобки, иначе они воспринимаются как завершение IF, что и приводит к ошибке (неожиданный контент после IF). @echo off SET ORACLE_SID=SID1 IF 1==1 ( echo *.dispatchers='(PROTOCOL=TCP^) (SERVICE=%ORACLE_SID%2XDB^)' >>D:\1.TXT )

среда, 5 февраля 2020 г.

Транзакции в git'е

#git #bat


Есть батник, который выполняет некоторый набор действий. В том числе есть коммиты
в разные ветки и создание тега. Скрипт НЕ делает push.

Хотелось бы, чтобы в случае ошибки на одном из шагов все коммиты и теги созданные
скриптом автоматически откатывались. Как такое можно сделать?
    


Ответы

Ответ 1



если изменения ограничиваются коммитами в существующие ветки и созданием меток, то можно сохранить резервную копию каталога refs, находящегося внутри хранилища (обычно — каталога .git). что-нибудь вроде: $ tar -cf /путь/к/архиву .git/refs в нём и сохраняются все указатели (и коммиты, на которые они указывают) — и ветки (branches) и метки (tags). если же вносимые изменения затрагивают что-то более глобальное (переименование/создание/удаление веток или удалённых хранилищ, изменения в конфигурации хранилища и т.п.), то стоит сохранять и файл config: $ tar -cf /путь/к/архиву .git/refs .git/config для «отката» достаточно удалить этот каталог и восстановить из резервной копии. что-нибудь вроде: $ rm -r .git/refs; tar -xf /путь/к/архиву а рабочую копию можно привести к нужному состоянию, как и обычно, командой checkout: $ git checkout коммит-или-ветка-или-метка при желании от накопившегося «мусора» локальное хранилище можно «почистить» командой gc: $ git gc

Ответ 2



Правильный, качественный способ - сделать локальный clone. Лишнего копирования при этом не должно быть When the repository to clone from is on a local machine, this flag bypasses the normal "Git aware" transport mechanism and clones the repository by making a copy of HEAD and everything under objects and refs directories. The files under .git/objects/ directory are hardlinked to save space when possible. то есть, если git сможет - он сделает hardlink на .git/objects/ - что обеспечит быстрое копирование. Если после всех изменений нужно сделать откат - просто удаляем папку с склонированной репой. Если все ок, просто делаем git push и снова удаляем склонированную репу. Да, push нужно будет делать аккуратно и как минимум добавить --tags. Но можно применить трюк с переименованием. То есть, папку с репой удаляем, а свежосклонированную переименновываем.

1. Как с помощью bat файла узнать где лежит этот файл? 2. Как задать системную переменную в cmd, которая не исчезнет после перезагрузки?

#windows #cmd #bat



Как с помощью bat файла узнать где лежит этот файл?

Бат файл выполняет python скрипт, но при запуске его, он начинает путь с c:\User\
а, надо чтобы запускался с места где лежит байт файл, причем все это должно быть не
жестко привязано.
Как задать системную переменную в cmd, которая не исчезнет после перезагрузки?

При вводе Set path = %path%variable в системную перемену добавляется строка variable,
но после перезагрузки системы она исчезает. Как сделать чтобы не исчезала?

    


Ответы

Ответ 1



Нулевым параметром в любой bat-файл передается путь к нему. Применение модификатора позволяет получить папку: echo %~dp0 Добавить запись в реестр: % reg add HKCU\Environment /v VariableName /t REG_SZ /d "Variable value" Переменная станет видимой после следующего входа в систему.

Ответ 2



По второму вопросу запись в реестр вручную неудобен, т.к. изменение не действует на текущий сеанс. Ответ в команде: setx /? С учетом замечаний дополню ответ. Необходимо воспользоваться в скрипте двумя командами. Первая записывает параметр в реестр для будущих сеансов. Вторая команда задает значение параметра для текущего сеанса. @setx var0 Value @set var0=Value

понедельник, 3 февраля 2020 г.

Запуск bat-файла из Java

#java #bat


Как запустить bat-файл из программы на java?
    


Ответы

Ответ 1



Runtime.getRuntime().exec("cmd /c FullFileName.bat"); Вместо FullFilePath.bat вставляете полный/относительный путь к вашему bat-файлу, например: Runtime.getRuntime().exec("cmd /c D:/BatFileName.bat"); Если вам потребуются какие-то особые параметры запуска bat-файла (вместо /c), то посмотрите список параметров данной комманды в коммандной строке (cmd /?).

Ответ 2



Рекомендую использовать ProcessBuilder ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/C", "pathToYourFile.bat"); Process process = processBuilder.start();

воскресенье, 2 февраля 2020 г.

Как запустить .bat файл в бэкграунде?

#cmd #bat


Имеется .bat файл, который при запуске начинает выполнять различные действия в command
line. Есть ли возможность сделать так чтоб функционал .bat файла выполнялся, но при
этом чтоб сам comand line был в бэкграунде ( вернее говоря чтоб пользователь не видел,
разве что только в TaskManager ) ?
    


Ответы

Ответ 1



Средствами командного процессора этого сделать нельзя. Но можно, например, запустить процесс в скрытом окне, используя запускающий VSB-скрипт... хотя разумнее весь батч переписать на VBS или PS. UPD: По просьбе ТС подробнее. Создай на диске C: каталог \Temp. Создай в нём 2 файла. A.BAT ping -n 1000 127.0.0.1 > c:\temp\ping.txt B.VBS Set WshShell = WScript.CreateObject("WScript.Shell") WshShell.Run "C:\Temp\a.bat",0 Открой Диспетчер задач, перейди на вкладку "Процессы". Запусти файл b.vbs на исполнение (просто двойной клик по нему). Убедись, что: В процессах появятся, и через некоторое время исчезнут cmd.exe и ping.exe. В каталоге появится файл ping.txt, и, пока не завершатся процессы по п. 1, файл будет заблокирован. В файле сохранён протокол работы утилиты ping. Ни окно CMD, ни окно PING на панели задач не появляется. И можно не спешить скакать по окнам, пинг будет работать минут 10-15...

Ответ 2



Воспользуйтесь дополнительной программой cmdow https://ritchielawrence.github.io/cmdow/ cmdow /run /hid myprog.bat

пятница, 24 января 2020 г.

Как в винде обрезать файл до нужного размера?

#windows #cmd #bat


Именно обрезать, а не скопировать частично. Соответственно, у винды нет богатых инструментов
на все случаи жизни, как например во фре:
truncate file.goy

Нужна такая штука для теста из-под MSBiuld скрипта.     


Ответы

Ответ 1



Вот для скрипта не знаю, а для Си (MinGW gcc) есть функция ftruncate(), позволяющая урезать файл. Простейшая программулька: #include #include #include main (int ac, char *av[]) { if (ac < 3) { fprintf (stderr,"Invalid usage\nUse: truncate SIZE FILE\n"); exit (1); } off_t size = atoi(av[1]); if (size < 0) // здесь можно что-то другое, например с конца файла size = 0; FILE *f = fopen(av[2],"r+"); if (!f) { perror(av[2]); exit (-1); } if (ftruncate(fileno(f), size)) { perror("truncate"); exit (-1); } exit (0); }

суббота, 11 января 2020 г.

Есть ли возможность при запуске .bat файла установить факт был ли он запущен вручную или автоматически(Task sheduler)?

#windows #bat #автоматизация #task #users


OC: Windows 2008 R2 Enterprise

Моя ситация: С помощью Task Sheduler ежедневно запускается определенный .bat файл.
Иногда есть потребность запускать его вручную.

Моя задача: При ручном запуске от Юзера, после прохождения команд оставить консоль
открытую (Pause) чтобы прочитать логи. При этом после запуска с помощью Task Sheduler
процесс должен терминироваться без Паузы. %USERNAME% не подходит, так как TS запускает
бптник от того же пользователя, что и запускает его вручную.

Есть ли возможность определить запускает батник Task Sheduler?
Может можно терминировать программу другим способом? 
Например через минуту после того как она дойдет до конца?
    


Ответы

Ответ 1



Вариант 1. Настройте запуск этого самого батника с параметром. В самом батнике проверяйте параметр: if "%1"=="" pause или вот так: if not "%1"=="nopause" pause Вариант 2. Научите пользователя запускать батник не двойным кликом - а как полагается, из командной строки. Командная строка не закрывается просто так. Вариант 3. Научите пользователя запускать батник используя FAR Manager. Там можно посмотреть консольный вывод скрыв панели (Ctrl+O) Но самым "красивым" способом я считаю создание отдельного ярлыка для батника. В этом ярлыке настраивается запуск файла через cmd с ключом /k. Ключ /k означает "выполнить команду и не закрывать консоль":

Ответ 2



Есть ли возможность определить запускает батник Task Sheduler? В принципе, эту информацию можно вытащить (см. комментарий @avp к посту) Видно, что можно поискать родителя и сравнить с svchost.exe. Однако, мне кажется, что лучше решить вашу задачу другим способом. Можно передавать при запуске из таск шедулера дополнительный параметр, который опускать при ручном запуске. Когда батник получит управление -- проверить, с каким параметром был вызван. Если вручную -- запустить дополнительную команду (паузу). По-моему весьма тривиальный и логичный воркэраунд.

Ответ 3



В Task Scheduler запускать VbScript, который будет запускать батник и после отработки процесса завершать его. Терминировать процесс можно так. var WshShell = WScript.CreateObject("WScript.Shell"); WshShell.Run("taskkill /IM iexplore.exe", 0);

четверг, 9 января 2020 г.

как в bat файле сделать так, чтобы после выполнения bat файл не закрывался

#bat


Как в bat файле сделать так, чтобы после выполнения bat файл не закрывался?
    


Ответы

Ответ 1



Можно помледней строкой поместить что-то из этого: pause cmd Либо запускать так: cmd /k smth.bat или даже так (если он иногда делает exit): cmd /k cmd /c smth.bat

суббота, 28 декабря 2019 г.

BAT-Синтаксис

#bat #cmd


Допустим в батнике:

cd C:\Program Files\path\test\  
start someprg.exe

Как после выполнения этих команд вернуться обратно в директорию к батнику, где бы
он не находился?    


Ответы

Ответ 1



На самом деле оба предложенных решения возвращают запомненную рабочую директорию, что не соответствует буквальному условию задачи: вернуться обратно в директорию к батнику, где бы он не находился Сменить директорию на ту, в которой расположен батник, можно так: CD /D A:\SOME\ REM делаем что-либо с относительными путями CD /D "%~dp0"

Ответ 2



См. help set в cmd set curdir=%cd% cd c:\ushare dir cd %curdir% Что-то в таком духе.

Ответ 3



Иногда может быть полезным воспользоваться командами PUSHD (переход в папку и запоминание старой) и POPD (возврат в запомненную папку) PUSHD папка REM Что-то полезное делаем POPD

Ответ 4



Лучше всего в данном случае использовать переменные: set up=%cd% Rem здесь тело батника cd %up%

пятница, 27 декабря 2019 г.

Список локальных пользователей bat-файлом

#windows #bat #список


Задача сделать средствами bat-файла список локальных пользователей
с параметрами вроде времени последнего входа и действие пароля.

Как можно ли объединить выполнение
    net user user1
    net user user2
    и т.п.

и отфильтровать вывод на определенные параметры.
    


Ответы

Ответ 1



Команда net user выводит имена пользователей таблицей: в 3 столбца шириной 25 символов. Получается, нужно собрать все строки таблицы в строковую переменную, а затем распарсить её. Проще воспользоваться командой, которая сразу выведет имена локальных пользователей: wmic useraccount where (localaccount="True") get Name. А для каждого полученного имени уже заставить в цикле выводить команду: net user <имя>

Объединить бинарные файлы

#windows #nodejs #файлы #bash #bat


В файле join.txt по одному на строке заданы имена файлов, которые надо объединить
в порядке следования. Хочу это сделать в консоли.

Попытался сделать так (в командной строке, не в батнике):

for /f "tokens=*" %f in (join.txt) do type "%f" >>result.bin


но в одном из случаев где-то потерялся байт - суммарный размер не сходится на 1 байт
и при сравнении с правильным файлом видно, что пропущен байт с кодом 1A:



Как объединить файлы так, чтобы бинарные данные не пострадали?
    


Ответы

Ответ 1



Если используется Windows 10, в котором установлена линуксовая подсистема, то вместо командной строки можно использовать bash: while read f || [[ -n $f ]]; do cat "$f" >>result.bin done

Ответ 2



В общем, с командной строкой ничего не придумал и написал скрипт для node.js: var fs = require('fs'); var filename = "join.txt"; // process.argv[2]; var dest = "result.bin"; // filename.replace(/\[names\](\.\w+)\.txt$/, "[full]$1"); if (filename === dest) { console.error("Can't determine dest filename"); return; } var files = fs.readFileSync(filename, "utf8").split(/\r?\n/); var resStream = fs.createWriteStream(dest, { flags: "wx" }); function go(i) { if (i === files.length) return resStream.end(); var cur = fs.createReadStream(files[i]) cur.pipe(resStream, {end:false}); cur.on('end', () => go(i+1)); } go(0);

Ответ 3



Решается средствами batch. Нужно просто копировать всё в результирующий файл. Создаем пустой файл, затирая старый. Затем все, найденное что в файл-списке, помещаем в результат. @copy /y nul result.bin @for /f "tokens=*" %%f in (join.txt) do copy /b result.bin +"%%f" result.bin

понедельник, 16 декабря 2019 г.

Узнать версию удаленной OS

#windows #bat #powershell


Есть удаленный компьютер, под какой-то версией Windows (начиная с WinXP Home и заканчивая
Win10). Компьютер не входит в домен, но на нем установлен RAdmin Server.

Нужно определить версию и редакцию ОС.

Т.к. компьютеров много (~300), то нужно что-то автоматизированное.

Пробовал

(Get-WmiObject Win32_OperatingSystem -computer "Имя компа").name


но для недоменных компьютеров возвращает "Отказано в доступе (E_ACCESSDENIED)"

Может можно как-то заскриптовать работу с RAdmin?

Update

Удалось автоматизировать вход на удаленную машину через Radmin Telnet. Теперь вопрос
- как получить редакцию ОС?

ver


возвращает

Microsoft Windows XP [Версия 5.1.2600]


а нужно еще редакцию Home или Professional

PowerShell на XP не установлен
    


Ответы

Ответ 1



wmic os get Caption,CSDVersion /value или (но у меня systeminfo думает ну очень долго) systeminfo | findstr /B /C:"OS Name" /C:"OS Version" Источник: https://www.windows-commandline.com/find-windows-os-version-from-command/

Ответ 2



Полный ответ выглядит так (решение на JScript) Запускаем RadminViewer в режиме telnet var proc = WshShell.Exec('radmin.exe /connect:' + host + ' /telnet'); Ждем какое-то время и через SendKeys вбиваем логин и пароль соединения WScript.Sleep(1000); WshShell.AppActivate(proc.ProcessID); WshShell.SendKeys("user{TAB}"); WshShell.SendKeys("pass{ENTER}"); если в системе существует и третья и вторая версия Radmin (которая не требует имени пользователя), то можно использовать такой код WshShell.AppActivate(proc.ProcessID); // Три Shift+Tab WshShell.SendKeys("+{TAB}+{TAB}+{TAB}"); // Если у нас вторая версия, то мы стоим на поле для ввода пароля WshShell.SendKeys("pass"); // Переместились на предыдущий контрол WshShell.SendKeys("+{TAB}"); // для второй версии мы попали на кнопку "Отмена", для третьей на поле для ввода пароля WshShell.SendKeys("pass"); // Переместились на предыдущий контрол WshShell.SendKeys("+{TAB}"); // для второй версии мы попали на кнопку "OK", для третьей на поле для ввода логина WshShell.SendKeys("user"); WshShell.SendKeys("{ENTER}"); Делаем паузу на установку соединения и на удаленной машине формируем bat-файл WScript.Sleep(1000); WshShell.AppActivate(proc.ProcessID); // Получение информации и сохранение ее в info.data cmd('echo systeminfo ^> info.data >> info.bat'); // На WinXP Home нет файла systeminfo, поэтому если вызов завершился неудачно cmd('if errorlevel 1 ( >> ' + cmdFile); // скачиваем его с FTP сервера cmd('echo ftp -s:get.ftp -n ' + ftpServer + ' >> info.bat'); cmd('echo expand systeminfo.cab systeminfo.exe >> ' + cmdFile); cmd('echo systeminfo ^> ' + datFile + ' >> ' + cmdFile); cmd('del systeminfo.exe >> ' + cmdFile); cmd('del systeminfo.cab >> ' + cmdFile); cmd(')>> ' + cmdFile); // Сжимаем полученный файл cmd('echo makecab info.data info.data.cab >> info.bat'); // И отправляем его с удаленной машины по FTP cmd('echo ftp -s:info.ftp -n ' + ftpServer + ' >> info.bat'); Формируем набор команд для скачивания файла с FTP cmd('echo USER ftp_user ftp_pass >> get.ftp'); cmd('echo GET systeminfo.cab >> get.ftp'); cmd('echo QUIT >> get.ftp'); Формируем набор команд для закачивания файла на FTP cmd('echo USER ftp_user ftp_pass >> info.ftp'); cmd('echo PUT info.data.cab >> info.ftp'); cmd('echo QUIT >> info.ftp'); Запускаем полученный bat-файл cmd("info.bat"); И закрываем сессию cmd("exit"); Функция cmd() определена так function cmd(command) { WshShell.SendKeys(command.replace(/[\^%+~\(\)]/g, "{$&}") + "{ENTER}"); WScript.Sleep(100); } Единственный минус метода - невозможность получить статус соединения от radmin С учетом того обстоятельства, что команды systeminfo нет в редакциях WinXP Home и его приходится заливать вручную, целесообразнее написать свою утилиту, которая скачается с FTP сервера и выполнит все необходимые манипуляции

воскресенье, 15 декабря 2019 г.

Как вызвать bat файл перед наполнением инсталлятора?

#bat #inno_setup


Мне нужно, чтобы файлы, помещающиеся в инсталлятор, сначала упаковывались upx'ом.
Для этого у меня есть .\upx.bat. Что нужно сделать, чтобы перед помещением файлов в
инсталлятор вызывался этот bat?
    


Ответы

Ответ 1



Тут может быть, как минимум, 2 пути: Написать еще один BAT-файл, который бы сначала вызывал ваш upx.bat, а затем бы вызывал InnoSetup с скриптом сборки инсталлятора, например, написав в этом BAT-файле так: C:\Path_to_InnoSetup\compil32 /cc "c:\isetup\my installer scips\my script.iss" О параметрах командной строки компилятора можно почитать тут. Использовать вызов BAT-файла upx.bat из Inno Setup непосредственно перед сборкой инсталлятора (полагаю, для вас это наиболее удобный вариант). Реализуется этот способ написанием в вашем скрипте команды препроцессора Exec(), например, так: #expr Exec("c:\upx.bat"). В этом случае компилятор InnoSetup выполнит ваш BAT-файл, а на время его выполнения приостановит процесс компиляции.

Перенаправление потоков в командном файле (CMD, BAT)

#bat #cmd


Есть некоторая необходимость производить логирование работы программы, при этом не
хотелось бы терять возможность отображения данных на экране консоли.

Команда:

dir > List.txt


произведет запись каталогов и файлов текущей директории в указанный файл. Хотелось
бы, чтобы данные также еще отобразились в консоли. Есть возможность наверняка такая,
например:

dir > list.txt 2>&1


но никак не соображу, как можно один поток писать и на экран и в файл.
    


Ответы

Ответ 1



Если у вас нет доступа к утилите tee, вы можете написать и скомпилировать её сами. Например, так: /* Tee utility by VladD Use it in whichever way you like Hopefully it doesn't do anything bad, but no warranty Compiles with MSVC 2012 */ #include "stdafx.h" // comment this line out if compiling with non-Microsoft compiler #include #include #include #include #include using namespace std; bool append = false; char** curr_arg; vector target_streams; vector stream_names; bool have_open_error = false; bool have_io_error = false; void evaluate_args() { for (; *curr_arg; curr_arg++) { string arg(*curr_arg); if (arg == "--") { curr_arg++; break; } else if (arg == "-a") { append = true; } // add more arguments here else if (arg.size() > 0 && arg[0] == '-') { cerr << "Unknown argument: " << arg << endl; exit(1); } else { break; } } } void create_streams() { auto openmode = ios::out | (append ? ios::app : ios::trunc); target_streams.push_back(&cout); stream_names.push_back("-"); for (; *curr_arg; curr_arg++) { string arg(*curr_arg); ostream* p; if (arg == "-") { p = &cout; } else { p = new ofstream(arg, openmode); if (!*p) { delete p; cerr << "Cannot open file `" << arg << "'" << endl; have_open_error = true; return; } } target_streams.push_back(p); stream_names.push_back(arg); } } void destroy_streams() { for (auto p : target_streams) { if (p != &cout) delete p; } } void process() { string line; while (getline(cin, line)) { for (size_t i = 0; i < target_streams.size(); i++) { auto p = target_streams[i]; if (!p) continue; (*p) << line << endl; if (!*p) { cerr << "Error occured writing to stream `" << stream_names[i] << "'" << endl; delete p; target_streams[i] = nullptr; have_io_error = true; } } } } int main(int argc, char* argv[]) { curr_arg = argv + 1; evaluate_args(); create_streams(); process(); destroy_streams(); return (have_open_error ? 0x2 : 0) | (have_io_error ? 0x4 : 0); }

Ответ 2



В shell и его потомках есть утилита tee, которая как раз предназначена для того, чтобы перенаправлять потоки и одновременно записывать их в файл. man tee: tee [ -ai ] [ File ... ] The tee utility copies standard input to standard output, making a copy in zero or more files. The output is unbuffered. The following options are available: -a Append the output to the files rather than overwriting them. -i Ignore the SIGINT signal. Самый простой способ получить к ней доступ — установить cygwin, а самый простой способ его установить — через chocolatey. После этого у вас появится возможность писать скрипты на bash и пользоваться соответствующим набором утилит. Для одной конкретной задачи это, возможно, слишком сложное решение. Но если необходимость в автоматизации и скриптах возникает часто, то в долгосрочной перспективе это, наверняка, будет оптимальным решением.

Ответ 3



Есть способ, конечно же...и не один. Самое первое, что мне пришло в голову, так это объединение команд: dir > C:\log.txt && dir Можно также тупо сначала писать логи в файл, а затем сразу же выводить их оттуда, но данный способ основан, опять же на объединении команд( и способ костыльный, имхо ).

Ответ 4



тут дали пример unix-like, так если скачать UnxUtils с sourceforge, то вполне можно использовать. Там есть команда tee отдельным exe

Ответ 5



Вот так: dir >list.txt >&2 или dir >list.txt 1>&2

среда, 11 декабря 2019 г.

Запуск программы с параметром: точный путь неизвестен

#windows #bat #командная_строка


На клиентских ПК установлено некоторое ПО "ПРОГРАММА", "ПРОГРАММА" может иметь разные
версии, и, соответственно, установлено по разным путям. Есть файл, имеющий некое расширение
".XXX", это расширение ассоциировано с "ПРОГРАММА", т.е. при даблклике в проводнике
Windows по этому файлу открывается "ПРОГРАММА" с содержимым файла. При вводе в командной
строке пути к этому файлу также открывается "ПРОГРАММА". Здесь все нормально.

Теперь задача: нужно открыть определенный файл, имеющий расширение ".XXX" в "ПРОГРАММА",
но с дополнительным параметром (он известен).

Как это сделать средствами командной строки?

Если это невозможно, могу написать приложение (C#), которое будет брать где-то в
реестре путь к программе ассоциированной с расширением ".XXX" и запускать, но, при
условии, что это не потребует каких-то привилегий.

ОС: Windows 7 SP1



Пример для воспроизведения проблемы:

Имеется установленный Notepad++, он ассоциирован с текстовыми файлами с расширением
".TXT", также у него имеется параметр -ro для открытия файла в режиме только для чтения.
Путь до самого приложения неизвестен.

Если я в командной строке ввожу

"C:\Program Files\Notepad++\notepad++.exe" "C:\Users\User\Desktop\1.txt"


то файл открывается в нормальном режиме

Если ввожу:

"C:\Program Files\Notepad++\notepad++.exe" "C:\Users\User\Desktop\1.txt" -ro


то в режиме только для чтения.

Но путь "C:\Program Files\Notepad++\notepad++.exe" мне неизвестен, поэтому я открываю так:

"C:\Users\User\Desktop\1.txt"


файл открывается в обычном режиме

Если же ввожу:

"C:\Users\User\Desktop\1.txt" -ro


то файл все равно открывается в обычном режиме

Как мне открыть файл в режиме только для чтения, но при этом путь к исполняемому
файлу неизвестен. Менять ассоциации файлов мне не подойдет.
    


Ответы

Ответ 1



static string AssocQueryString(AssocStr association, string extension) { const int S_OK = 0; const int S_FALSE = 1; uint length = 0; uint ret = AssocQueryString(AssocF.None, association, extension, null, null, ref length); if (ret != S_FALSE) { throw new InvalidOperationException("Could not determine associated string"); } var sb = new StringBuilder((int)length); // (length-1) will probably work too as the marshaller adds null termination ret = AssocQueryString(AssocF.None, association, extension, null, sb, ref length); if (ret != S_OK) { throw new InvalidOperationException("Could not determine associated string"); } return sb.ToString(); } Вызывать с AssocStr.ASSOCSTR_EXECUTABLE и ".txt". Пример кода взят из другого ответа на английском.

Ответ 2



В принципе установка ассоциации с типом файла позволяет выставить любой вызов который вам нужен. По умолчанию это выглядит как примерно как prog.exe "%1" где в %1 идёт имя файла по которому кликнули. Можно это поменять с помощью ftype и assoc: ftype MyProgramType=%ProgramFiles%\MyDir\MyProgram.exe "%1" /arg1 /arg2 assoc .xxx=MyProgramType при даблклике или вызове из командной строки тогда помимо имени файла будут переданы /arg1 /arg2

Ответ 3



В качестве возможной идеи, можно добавить ваше приложение в App Paths. При этом его можно будет запускать без полного пути и под альтернативным именем: n -ro text.txt Но если идти этим путём, можно и просто положить bat-файл с новым названием в доступном месте.

Ответ 4



Я когда-то решал задачу запуска Access-а, который мог быть установлен по разным путям. Брал путь установки из реестра. @echo off for /f "skip=1 tokens=2,*" %%i in ('reg query "HKLM\Software\Microsoft\Office\11.0\Access\InstallRoot" /v "Path"') do set PathToAccess="%%j" cd /d %PathToAccess%\ start msaccess.exe P:\Bank\CredStage\Orders_journal.mde /WRKGRP P:\Bank\CredStage\Security.mdw

вторник, 10 декабря 2019 г.

Быстрое переключение мониторов

#windows #bat #поиск_программ #монитор


Как изменять состояние Multiple displays одной командой?


    


Ответы

Ответ 1



Как говорится в https://stackoverflow.com/a/16791451/4928642, можно запустить стандартную программу DisplaySwitch с одним из следующих параметров: /clone - Duplicate these displays /external - Show desktop only on 2 /internal - Show desktop only on 1 /extend - Extend this displays Соответственно, можно создать нужные ярлыки и запускать их.

четверг, 28 ноября 2019 г.

Как проверить, спит ли диск?

#c_sharp #c++ #windows #winapi #bat


Если в Windows включено автоматическое отключение дисков при неактивности, то как
программно проверить, спит диск или включен, естественно, не разбудив его при этом?
    


Ответы

Ответ 1



Вот таким способом удалось проверить PowerState диска и не разбудить его при этом. Моя домашняя система очень тихая, запуск и остановка диска отчетливо слышны. Более весомое доказательство: при повторных запусках состояние не изменяется, в отличие от варианта с получением хендла от файла. Правда не без ложки дегтя, требуются права администратора и нужно знать порядковый номер проверяемого физического диска в системе. 99% кода примеры с PInvoke, моя только компоновка в рабочий вариант. void Main() { String status = String.Empty; bool fOn = false; var driveX = 1; var hFile = CreateFileW($@"\\.\PHYSICALDRIVE{driveX}", FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Offline, IntPtr.Zero); bool result = GetDevicePowerState(hFile, out fOn); if (result) { if (fOn) { status = "Disk is powered up and spinning"; } else { status = "Disk is sleeping"; } } else { status = "Cannot get Disk Status"; } Console.WriteLine(status); } //https://www.pinvoke.net/default.aspx/kernel32.CreateFile [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] static extern IntPtr CreateFileW( [MarshalAs(UnmanagedType.LPWStr)] string filename, [MarshalAs(UnmanagedType.U4)] FileAccess access, [MarshalAs(UnmanagedType.U4)] FileShare share, IntPtr securityAttributes, [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, [MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes, IntPtr templateFile); //https://www.pinvoke.net/default.aspx/kernel32.GetDevicePowerState [DllImport("kernel32.dll")] static extern bool GetDevicePowerState(IntPtr hDevice, out bool pfOn); Ограничения: системный диск спит только когда спит вся система (во всяком случае на Windows). проверка не имеет смысла, если физический диск в системе единственный, он в любом случае будет активен, если вся система не спит (см. выше). не уверен насчет SSD и прочих сменных носителей, проверять было не на чем, на единственном SDD живет система и он никогда не спит.

Ответ 2



Можно подумать в сторону командной строки, что то вроде

Ответ 3



Никак. За остановку диска при отсутствии обращений к нему отвечает прошивка диска. Винда может остановить диск только когда за компом никто не работает.

пятница, 14 июня 2019 г.

Как сделать бесконечный цикл в cmd?

Нужно бесконечно повторять некую команду. как это реализовать в командной строке?


Ответ

Если речь идёт непосредственно о командной строке
то стоит воспользоваться циклом for
for /l %q in (0) do echo Loop
Если же речь о bat-файле
в предыдущей команде можно удвоить знак процента:
for /l %%q in (0) do echo Loop
но лучше воспользоваться меткой и goto
:loop echo Loop goto loop