<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; CMD/BAT]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;fid=12&amp;type=atom" />
	<updated>2025-09-06T09:21:56Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/index.php</id>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: звуки (3 разных + бонус: азбука Морзе)]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=18491&amp;action=new" />
			<summary type="html"><![CDATA[<p>Два примера, как вывести звук из батника:</p><div class="codebox"><pre><code>@ echo off
setlocal enabledelayedexpansion

pause
echo Звуковой сигнал №1
call :beep1

pause
echo Звуковой сигнал №2
call :beep2

exit /b

:: Звуковой сигнал через символ с кодом 7 (Alt + 07)
:beep1
setlocal
0&lt;nul set /p =[BEL]
endlocal &amp; exit /b

:: Звуковой сигнал через choice
:beep2
echo 0y | choice /c y /n&gt;nul
exit /b</code></pre></div><p><strong>[BEL]</strong> - это непечатный символ с кодом 7. В форум его вставить нельзя, так что работающий пример качайте из вложения.</p><p>Подпрограмма <strong>beep1</strong> выводит звук через символ с кодом 7.<br />Подпрограмма <strong>beep2</strong> выводит звук через команду choice.</p><p>Не факт что везде будет работать, не проверял, но у меня оба метода работают и звуки разные.</p><br /><p><strong>Произвольный звуковой сигнал</strong></p><p>Еще один вариант воспроизвести звук, причем произвольный:<br /></p><div class="codebox"><pre><code>powershell -c &quot;[console]::beep(800,200)&quot;</code></pre></div><p>800 - частота в Гц (от 37 до 32767).<br />200 - продолжительность в мс (от 1).</p><br /><p><strong>Сигнал SOS</strong></p><p>А вот и пример реализации сигнала SOS через звуки и мигание экраном:</p><div class="codebox"><pre><code>@ echo off
setlocal enabledelayedexpansion

cls
title Сигнал SOS

:sos
call :M_S
call :M_O
call :M_S
call :pause 2
echo.
goto sos

exit /b

:: O: ---
:M_O
call :dash
call :dash
call :dash
exit /b

:: S: ...
:M_S
call :dot
call :dot
call :dot
exit /b

:: Точка (Морзе)
:dot
setlocal
0&lt;nul set /p =.
color f0
call :beep2
color 07
endlocal &amp; exit /b

:: Тире (Морзе)
:dash
setlocal
0&lt;nul set /p =-
color f0
call :beep2
call :pause
color 07
endlocal &amp; exit /b

:: Звуковой сигнал через choice
:beep2
echo 01 | choice /c 1 /n&gt;nul
exit /b

:: Задержка в сек (0 - короткая задержка)
:pause
setlocal
set t=%1
if &quot;%t%&quot;==&quot;&quot; set t=0
timeout /t %t% &gt;nul
endlocal &amp; exit /b
</code></pre></div><p>Так как звук подается вызовом подпрограммы beep2, которая работает через choice, то и непечатных символов тут нет. Можно копировать код прямо с форума.</p><p>Обсуждение тут - <a href="http://forum.script-coding.com/viewtopic.php?id=18487">CMD/BAT: звуки (2 разных + бонус: сигнал SOS)</a></p>]]></summary>
			<author>
				<name><![CDATA[Arigato]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=29277</uri>
			</author>
			<updated>2025-09-06T09:21:56Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=18491&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: Управляющие последовательности ANSI/ECMA-48 (цвет и прочее)]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=18490&amp;action=new" />
			<summary type="html"><![CDATA[<p><a href="https://ru.wikipedia.org/wiki/%D0%A3%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D1%8F%D1%8E%D1%89%D0%B8%D0%B5_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_ANSI">Управляющие последовательности ANSI</a> — символы, встраиваемые в текст, для управления форматом, цветом и другими опциями вывода в текстовом терминале.</p><p>В Microsoft Windows поддержка управляющих последовательностей ANSI появилась начиная с Windows 10.</p><p>Для управления выводом текста в консоль используются специальные ESC-коды. Выглядят они так:</p><p><strong>ESC[&lt;параметры&gt;&lt;буква-команда&gt;</strong></p><p>ESC[ — признак начала управляющей последовательности. ESC — непечатный символ с кодом 27 (U+001B). Набирается посредством Alt+27 или Alt+027, на экране выглядит как вопросик в квадрате или иначе, в зависимости от редактора.<br />&lt;параметры&gt; — цифры (иногда с ; ), указывают режим или количество.<br />&lt;буква-команда&gt; — финализирующий символ, указывающий какое именно действие.</p><p>Так как набирать непечатный символ ESC не очень удобно, да и скопировать текст с непечатными символами может быть проблематично (допустим, невозможно поделиться кодом на форуме), то можно программно получить префикс для <a href="https://ru.wikipedia.org/wiki/%D0%A3%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D1%8F%D1%8E%D1%89%D0%B8%D0%B5_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_ANSI#CSI-%D0%BA%D0%BE%D0%B4%D1%8B">CSI-кодов</a>. Вот код для получения CSI-префикса:</p><div class="codebox"><pre><code>:: Получаем префикс CSI = ESC + [
for /f &quot;delims=&quot; %%a in (&#039;echo prompt $E[^| cmd /q /d /k&#039;) do set &quot;CSI=%%a&quot;</code></pre></div><p><a href="http://forum.script-coding.com/viewtopic.php?id=18484">Тема для обсуждения</a></p>]]></summary>
			<author>
				<name><![CDATA[Arigato]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=29277</uri>
			</author>
			<updated>2025-09-04T07:33:12Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=18490&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: Получить температуру процессора]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=18452&amp;action=new" />
			<summary type="html"><![CDATA[<p>Батник выводит температуру процессора в градусах Цельсия с точностью до двух знаков после десятичной точки:</p><div class="codebox"><pre><code>@echo off
for /f &quot;skip=1 tokens=2 delims==&quot; %%A in (&#039;wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature /value&#039;) do (
   set Kel=%%~A
)
set /a Deg=Kel*10-27315
set CPU_Temp=%Deg:~0,-2%.%Deg:~-2%
echo CPU temperature: %CPU_Temp% C</code></pre></div><p>Батник надо запускать от администратора.</p><p><a href="https://forum.script-coding.com/viewtopic.php?id=18451">Тема для обсуждения</a></p>]]></summary>
			<author>
				<name><![CDATA[Arigato]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=29277</uri>
			</author>
			<updated>2025-05-22T07:06:53Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=18452&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: динамический вывод изображений из БД sqlite3]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=17234&amp;action=new" />
			<summary type="html"><![CDATA[<p><em>Без гарантий. Используете на свой страх и риск.</em></p><p>Можно попробовать динамичекий вывести BLOB-изображение из БД sqlite3 в окно HTA командой наподобие следующей:<br /></p><div class="codebox"><pre><code>
sqlite3 &quot;mysql_data.db&quot; &quot;select Hex(filestore.file) from filestore where filestore.id=1&quot;|xxd -r -u -ps|mshta.exe .\viewer.hta
</code></pre></div><p>Функция Hex() переводит данные BLOB-файла в формат Hex-дампа, который, в свою очередь, вновь преобразуется в строковые данные файла с помощью xxd, после чего полученная строка данных направляется в StdIn HTA-скрипта просмотра. Если не использовать функцию Hex() то BLOB-данные обрежутся по первому нулевому символу. xxd же удается передать строку данных содержащую \x0 символы в StdIn HTA-скрипта просмотра.</p><p>--------<br />CMD-сценарий предназначен для добавления и динамического просмотра BLOB-изображений из БД sqlite3. Запуск без параметров создает БД sqlite3 &quot;mysql_data.db&quot;, если таковая отсутствует, или предлагает выбрать индекс изображения для вывода. При перетаскивании значка изображения на файл скрипта происходит добавление файла(только одного) в БД. Не будет работать с кириллическими путями файлов.</p><p>Использована командная оболочка sqlite3.exe version 3.8.7.4.<br />Использован порт <a href="https://sourceforge.net/projects/xxd-for-windows/">xxd для Win32</a>.<br />Для преобразования изображения из строки в IPicture использован класс &quot;WIA.Vector&quot; библиотеки &quot;Microsoft Windows Image Acquisition Library (wiaaut.dll)&quot;<a href="http://forum.script-coding.com/viewtopic.php?pid=30088#p30088">(пример)</a>.<br />Для вывода изображения в окно HTA использован ActiveXControl &quot;Forms.Form.1&quot; библиотеки &quot;Microsoft Forms 2.0 Object Library (FM20.DLL)&quot;<a href="http://forum.script-coding.com/viewtopic.php?pid=12354#p12354">(пример)</a>.<br />См.также: <a href="http://forum.script-coding.com/viewtopic.php?id=8742">CMD/BAT + HTML: два в одном</a></p><p>OC Win 7</p><p><strong>sqimg.cmd</strong><br /></p><div class="codebox"><pre><code>
&lt;!-- :
::
:: Динамический просмотр изображений из БД sqlite3
::
@echo off
setlocal enableextensions enabledelayedexpansion

set &quot;dir1=%~dp0&quot;
set &quot;fl1=%~f1&quot;
set dbname=mysql_data.db

chdir /d %dir1%

rem ------------------------------------------------------------------
if not exist &quot;%dir1%%dbname%&quot; (
	echo create database %dbname%
	sqlite3 &quot;%dir1%%dbname%&quot; &quot;create table filestore (id INTEGER PRIMARY KEY ASC, name TEXT, crc TEXT, file BLOB)&quot;
	goto :stop
)
rem ------------------------------------------------------------------
if /i &quot;%fl1%&quot; equ &quot;&quot; (
	call :getview
) else (
	sqlite3 &quot;%dir1%%dbname%&quot; &quot;insert into filestore(name,crc,file) values(&#039;%~nx1&#039;,&#039;0&#039;,readfile(&#039;%fl1%&#039;))&quot;
	echo add &quot;%fl1%&quot;
)

:stop
echo EXIT
endlocal
pause
exit /b 0

rem ------------------------------------------------------------------
::
:: Просмотреть изображение
::
:getview

	set st=
	for /f &quot;usebackq tokens=*&quot; %%a in (`sqlite3 &quot;%dir1%%dbname%&quot; &quot;select filestore.id from filestore&quot;`) do (
		set st=!st! %%a
	)
	sqlite3 &quot;%dir1%%dbname%&quot; &quot;select filestore.id, filestore.name from filestore&quot;

	rem Выбор индекса
	rem ----------------------------------------------------------
	:label1

	echo Choose index of image; b - break:
	set /p x=&quot;&quot;
	if /i &quot;!x!&quot; equ &quot;b&quot; exit /b 0	

	set y=
	for /f &quot;usebackq tokens=*&quot; %%b in (`echo !st!^|findstr /r /i &quot;!x!&quot;`) do (
		set y=%%b
	)
	if /i &quot;!y!&quot; equ &quot;&quot; (
		echo No such index !x!
		goto :label1
	)
	rem ----------------------------------------------------------
	rem разделитель &#039;|&#039; пропускается xxd

	sqlite3 &quot;%dir1%%dbname%&quot; &quot;select Hex(printf(&#039;%%s|&#039;,filestore.name)), Hex(filestore.file) from filestore where filestore.id=!x!&quot;|xxd -r -u -ps|mshta &quot;%~f0&quot;
	goto :label1
--&gt;

&lt;HTML&gt;
&lt;HEAD&gt;
&lt;meta http-equiv=Content-Type content=&quot;text/html; charset=windows-1251&quot;&gt;
&lt;TITLE&gt;&lt;/TITLE&gt;
&lt;HTA:APPLICATION
        ID=&quot;oHTA&quot;
        APPLICATIONNAME=&quot;myApp&quot;
&lt;/HEAD&gt;

&lt;BODY SCROLL=&quot;YES&quot;&gt;
&lt;OBJECT id=&quot;form1&quot; CLASSID=&quot;CLSID:C62A69F0-16DC-11CE-9E98-00AA00574A4F&quot;&gt;&lt;/OBJECT&gt;
&lt;SCRIPT&gt;

	/*
	Просмотр изображения полученного через stdin в окне HTA
	Для преобразования изображения из строки в IPicture использован класс &quot;WIA.Vector&quot; библиотеки &quot;Microsoft Windows Image Acquisition Library (wiaaut.dll)&quot;
	Для вывода изображения в окно HTA использован ActiveXControl &quot;Forms.Form.1&quot; библиотеки &quot;Microsoft Forms 2.0 Object Library (FM20.DLL)&quot;
	*/

	adTypeBinary = 1
	adTypeText = 2
	adSaveCreateOverWrite = 2

	var re = /(.*)\|/i;

	var objForm = document.getElementById(&quot;form1&quot;);
	var objVector = new ActiveXObject(&quot;WIA.Vector&quot;);
	var objStream = new ActiveXObject(&quot;ADODB.Stream&quot;);
	var oFs = new ActiveXObject(&quot;Scripting.FileSystemObject&quot;);

	var objStdIn = oFs.GetStandardStream(0, false);

	//Переписать stdin в Stream(Text)
	with (objStream){
		Open();
		Type = adTypeText;
		Charset = &quot;windows-1251&quot;;
	}
	
	var sTxt = new String(objStdIn.Read(256));
	re.exec(sTxt);
	var fname = RegExp.$1;
	
	objStream.WriteText(sTxt.replace(re,&quot;&quot;));
	while (!objStdIn.AtEndOfStream){
		objStream.WriteText(objStdIn.Read(1024));
		
	}
	// Изменить тип Stream(Text) на Stream(Binary)
	objStream.Position = 0;
	objStream.Type = adTypeBinary;
	
	// Загрузить изображение
	objVector.BinaryData = objStream.Read();
	objStream.Close();

	if (typeof(objVector.ImageFile)==&quot;unknown&quot;){alert(&quot;Файл не является изображением.&quot;);window.close();}

	// Вывести изображение на Forms.Image.1 Control
	//===================================================
	objForm.style.width = objVector.ImageFile.Width + 5;
	objForm.style.height = objVector.ImageFile.Height + 5;

	var objImg = objForm.object.Controls.Add(&quot;Forms.Image.1&quot;, &quot;img1&quot;, true);
	objImg.AutoSize = true;
	objImg.Picture = objVector.Picture;
	document.title = fname;	
	
	/*
	// Сохранить файл
	sFilePath = oHTA.commandLine;
	sFileOut = sFilePath.substring(1,sFilePath.lastIndexOf(&#039;\\&#039;)+1) + &quot;copyof_&quot; + fname;
	try{
	objVector.ImageFile.SaveFile(sFileOut);
	}catch(e){alert(&quot;Ошибка сохранения:&quot;+String.fromCharCode(32)+e.description);}
	*/

&lt;/SCRIPT&gt;
&lt;/BODY&gt;
&lt;/HTML&gt;
</code></pre></div>]]></summary>
			<author>
				<name><![CDATA[Poltergeyst]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=83</uri>
			</author>
			<updated>2022-07-07T20:14:56Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=17234&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: дублирование вывода команды]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=17105&amp;action=new" />
			<summary type="html"><![CDATA[<p><em>Без гарантий. Используете на свой страх и риск.</em></p><p>Можно попробовать дублировать вывод StdOut консольной команды одновременно в консоль и файл:<br /></p><div class="codebox"><pre><code>
команда | CScript [имя скрипта] /параметры
</code></pre></div><p>CScript забирает выходной поток команды, после чего, с помощью WSH скрипта, возвращает его в консоль и дублирует в файл.<br />OC Win 7</p><p>Получение списка процессов:<br /><strong>plist.cmd</strong><br /></p><div class="codebox"><pre><code>
@set @x=1/*
::
:: Список процессов с дублированием вывода
::

 @echo off
 setlocal enableextensions
 rem chcp 1251&gt;nul

 wmic process list brief 2&gt;&amp;1|CScript /e:jscript &quot;%~f0&quot;
 pause
 exit /b 0

::--------------------------------------------
*/

redirect();
WScript.Quit();

//
// Дублирование вывода в консоль и файл
//
function redirect()
{

	var sdata;
	var oFs = new ActiveXObject(&quot;Scripting.FileSystemObject&quot;);
	//------------------------------------
	sFilePath = WScript.ScriptFullName;
	sFileOut = sFilePath.substring(0,sFilePath.lastIndexOf(&#039;\\&#039;)+1) + &quot;proclist.txt&quot;;

	var oStream = oFs.OpenTextFile(sFileOut, 2, true, 0);
	var ostdin = oFs.GetStandardStream(0, false);
	var ostdout = oFs.GetStandardStream(1, false);
	//------------------------------------
	sdata = ostdin.ReadAll();

	//Дублирование вывода
	ostdout.Write(sdata);
	oStream.Write(sdata);
	oStream.Close();
}
</code></pre></div><p>Тестирование rar и zip архивов с помощью 7z, рекурсивно, с выбором начального каталога:<br /><strong>7ztest.cmd</strong><br /></p><div class="codebox"><pre><code>
@set @x=1/*
::
:: Тест архивов с помощью 7z с выбором начального каталога и дублированием вывода
::

 @echo off
 setlocal enableextensions
 rem chcp 1251&gt;nul

 for /f &quot;tokens=*&quot; %%a in (&#039;CScript /nologo /e:jscript &quot;%~f0&quot; /choosedir&#039;) do set dir1=%%a
 if /i &quot;%dir1%&quot; equ &quot;&quot; (exit /b 0)

 rem [проверка на слеш в конце строки, на случай если выбран диск]
 
 if &quot;%dir1:~-1%&quot; equ &quot;\&quot; (set dir1=%dir1:~0,-1%)
 set dir1=&quot;%dir1%&quot;

 echo Init directory %dir1%
 pause

::
:: Проверка архивов с помощью 7z
::
::--------------------------------------------
 rem &quot;C:\Program Files\7-Zip\7z&quot; t -an -air!%dir1%\*.rar -air!%dir1%\*.zip -air!%dir1%\*.7z

 &quot;C:\Program Files\7-Zip\7z&quot; t -an -air!%dir1%\*.rar -air!%dir1%\*.zip 2&gt;&amp;1|CScript /e:jscript &quot;%~f0&quot; /doit
 pause
 exit /b 0

::--------------------------------------------
*/

var oArgs = WScript.Arguments
if (oArgs.Length==0){WScript.Quit();}

var rearg = /doit/i; 
var f = rearg.test(String(oArgs.Item(0)))
if (f){redirect();}else{choosedir();}
WScript.Quit();

//
// Диалог выбора целевого каталога на JScript
//
function choosedir()
{
	var oShell = new ActiveXObject(&#039;Shell.Application&#039;);
	var oFolder = oShell.BrowseForFolder(0, &quot;Выбор папки&quot;, 1, &quot;&quot;);
	
	if (Number(isNaN(oFolder))==1){WScript.Echo(oFolder.Self.Path);}
	
}

//
// Дублирование вывода 7z в консоль и файл
//
function redirect()
{
	var re1 = /path|ok/i;
	var re2 = /error|warning/i;
	var f1 = false;
	var f2 = false;
	var sdata;
	var oFs = new ActiveXObject(&quot;Scripting.FileSystemObject&quot;);

	//---------------------------------------------------------
	sFilePath = WScript.ScriptFullName;
	sFileOut = sFilePath.substring(0, sFilePath.lastIndexOf(&#039;\\&#039;)+1) + &quot;myfile.txt&quot;;

	var oStream = oFs.OpenTextFile(sFileOut, 2, true, 0);
	oStream.WriteLine(&quot;testing archives&quot;);

	var ostdin = oFs.GetStandardStream(0, false);
	var ostdout = oFs.GetStandardStream(1, false);

	//---------------------------------------------------------
	while (!ostdin.AtEndOfStream)
	{
		sdata = ostdin.ReadLine();
		ostdout.WriteLine(sdata);

		if (f2){oStream.WriteLine(sdata);}
		f1 = re1.test(sdata);
		f2 = re2.test(sdata);
		if (f1||f2){oStream.WriteLine(sdata);}
	}
	oStream.Close();
}
</code></pre></div>]]></summary>
			<author>
				<name><![CDATA[Poltergeyst]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=83</uri>
			</author>
			<updated>2022-05-06T18:55:47Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=17105&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: Определение кодировки файла (определение BOM)]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=16661&amp;action=new" />
			<summary type="html"><![CDATA[<p><strong><br />**********************<br />Скрипт имеет ограничение: он умеет определять кодировку только по наличию BOM. Для UTF-8 его наличие необязательно. Поэтому UTF-8 файлы без BOM не определяются. В процессе изобретения этого скрипта был найден еще один вариант. Он приведен в этой же теме ниже.<br />**********************<br /></strong></p><p>Сходная тема в соседнем разделе <a href="http://forum.script-coding.com/viewtopic.php?id=8491">WSH: Определение кодировки файла</a></p><p>Используются только возможности интерпретатора и стандартная команда FC для сравнения двух файлов. Хитрость заключается в <strong>двоичном сравнении</strong> специально созданного временного файла с искомым. Идея не моя, я ее вычитал где-то на форуме <a href="https://www.dostips.com/">https://www.dostips.com/</a>.</p><p>Пример использования:</p><div class="codebox"><pre><code>
&gt;powershell -c &quot;write \&quot;In math the Greek letter $([char]0x03C0) stands for 3.1415926\&quot; | out-file -encoding utf8 example-file&quot;

&gt;type example-file
я╗┐In math the Greek letter ╧А stands for 3.1415926

&gt;file-detect-bom.bat example-file
example-file: UTF-8

&gt;file-detect-bom.bat -b example-file
UTF-8
</code></pre></div><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;исходный код</div><div class="fancy_spoiler"><p>Актуальну версию можно найти здесь: <a href="https://github.com/ildar-shaimordanov/cmd.scripts/blob/master/file-detect-bom.bat">https://github.com/ildar-shaimordanov/c … ct-bom.bat</a></p><div class="codebox"><pre><code>
::Usage: file-detect-bom [OPTIONS] FILE...
::
::Detect the Byte Order Mark (BOM) in FILEs.
::
::  -b, --brief  Don&#039;t prepend filenames to output

@echo off

setlocal enabledelayedexpansion

set &quot;bom_brief=&quot;
if /i &quot;%~1&quot; == &quot;-b&quot;      set &quot;bom_brief=1&quot;
if /i &quot;%~1&quot; == &quot;--brief&quot; set &quot;bom_brief=1&quot;
if defined bom_brief shift /1

if &quot;%~1&quot; == &quot;&quot; goto :print_usage

:: ========================================================================

:: The following settings are based on information from the table
:: https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding
set &quot;bom_val_EFBBBF=UTF-8&quot;
set &quot;bom_val_FEFF=UTF-16BE&quot;
set &quot;bom_val_FFFE=UTF-16LE&quot;
set &quot;bom_val_0000FEFF=UTF-32BE&quot;
set &quot;bom_val_FFFE0000=UTF-32LE&quot;
set &quot;bom_val_2B2F76=UTF-7&quot;
set &quot;bom_val_F7644C=UTF-1&quot;
set &quot;bom_val_DD736673=UTF-EBCDIC&quot;
set &quot;bom_val_0EFEFF=SCSU&quot;
set &quot;bom_val_FBEE28=BOCU-1&quot;
set &quot;bom_val_84319533=GB-18030&quot;

:: ========================================================================

set &quot;bom_cmpfile=%TEMP%\bom_cmpfile&quot;
set /p &quot;=@@@@&quot; &lt;nul &gt;&quot;%bom_cmpfile%&quot;

:bom_begin_loop
if &quot;%~1&quot; == &quot;&quot; (
	del /f /q &quot;%bom_cmpfile%&quot; 2&gt;nul
	goto :EOF
)

for %%f in ( &quot;%~1&quot; ) do (
	call :detect_type &quot;%%~f&quot;

	if defined bom_brief (
		if defined bom_found echo:!bom_found!
	) else (
		echo:%%~f: !bom_found!
	)
)

shift /1
goto :bom_begin_loop

:: ========================================================================

:print_usage
for /f &quot;usebackq tokens=* delims=:&quot; %%s in ( &quot;%~f0&quot; ) do (
	if /i &quot;%%s&quot; == &quot;@echo off&quot; goto :EOF
	echo:%%s
)
goto :EOF

:: ========================================================================

:detect_type
set &quot;bom_found=&quot;

set &quot;bom_srcfile=%~1&quot;

if not exist &quot;%~1&quot; (
	echo:File not found: &quot;%~1&quot;&gt;&amp;2
	exit /b 1
)
if exist &quot;%~1\&quot; (
	set &quot;bom_found=directory&quot;
	goto :EOF
)
if %~z1 equ 0 (
	set &quot;bom_found=empty&quot;
	goto :EOF
)

set &quot;bom_bytes=&quot;
for /f &quot;tokens=1,2,3,4 delims=: &quot; %%a in ( &#039;
	fc /b &quot;%bom_cmpfile%&quot; &quot;%~1&quot; ^| findstr /n /r &quot;^00*[0-3]&quot;
&#039; ) do (
	set /a bom_diff=%%a-%%b
	if !bom_diff! equ 2 set &quot;bom_bytes=!bom_bytes!%%d&quot;
)

for /l %%n in ( 8, -2, 4 ) do for %%s in ( bom_val_!bom_bytes:~0^,%%n! ) do (
	set &quot;bom_found=!%%s!&quot;
	if defined bom_found goto :EOF
)
goto :EOF

:: ========================================================================

:: EOF
</code></pre></div></div></div><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;история изменений</div><div class="fancy_spoiler"><p><em>2021-10-14</em><br />-- несколько косметических изменений<br />-- &quot;молчаливое&quot; удаление временного файла<br />-- определение кодировки оформлено как подпрограмма<br />-- корректно сообщает о несуществующих файлах, пустых файлах и директориях<br />-- переименовал скрипт: &quot;bom_file.bat&quot; -&gt; &quot;file-detect-bom.bat&quot;</p><p><em>2021-10-13</em><br />После первой публикации нашел небольшой баг: если кодировка файла не определена, то следущий файл отображается в этой же строке. Например:<br /></p><div class="codebox"><pre><code>
Z:&gt;bom_file ascii_file utf8_file
ascii_file: utf8_file: UTF-8
</code></pre></div><p>Сейчас это исправлено.</p><p>Потом мне захотелось сделать скрипт еще лучше и я изменил несколько мест:<br />-- немного усложнил, но сделал более строгим сбор первых, не более 4 последовательных байт<br />-- оптимизировал фрагмент определения кодировки<br />-- упростил вывод результата</p><p><em>2021-10-11</em><br />Первая публикация</p><p>Историю изменений можно посмотреть по этим ссылкам:<br />-- <a href="https://github.com/ildar-shaimordanov/cmd.scripts/commits/master/bom_file.bat">https://github.com/ildar-shaimordanov/c … m_file.bat</a>.<br />-- <a href="https://github.com/ildar-shaimordanov/cmd.scripts/commits/master/file-detect-bom.bat">https://github.com/ildar-shaimordanov/c … ct-bom.bat</a></p><p>Я намеренно каждое исправление фиксировал отдельным коммитом.</p></div></div>]]></summary>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2021-10-13T20:54:25Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=16661&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/JS: msiprobe скрипт проверки и распаковки MSI файлов]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=16216&amp;action=new" />
			<summary type="html"><![CDATA[<p>msiexec стандартная утилита для установки/удаления приложений из MSI-файлов. У ней есть различные опции, в частности для распаковки файлов. Иногда может быть полезно. </p><p>Написал гибридный CMD/JS скрипт для проверки и распаковки MSI-файлов.</p><p>Примеры использования.</p><p>Посмотреть информацию о файле<br /></p><div class="codebox"><pre><code>
msiprobe filename.msi /property
</code></pre></div><p>Посмотреть содержимое файла<br /></p><div class="codebox"><pre><code>
msiprobe filename.msi /list
</code></pre></div><p>распаковать файл в некоторый каталог<br /></p><div class="codebox"><pre><code>
msiprobe filename.msi C:\TEMP\zzz
</code></pre></div><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;исходный код</div><div class="fancy_spoiler"><p>Актуальная версия лежит <a href="https://github.com/ildar-shaimordanov/cmd.scripts/blob/master/msiprobe.bat">здесь</a><br /></p><div class="codebox"><pre><code>
0&lt;/*! ::

::Probe and unpack a MSI file.
::
::Usage:
::    msiprobe msi-file /LIST
::    msiprobe msi-file /PROPERTY
::    msiprobe msi-file target-dir

@echo off

if /i &quot;%~2&quot; == &quot;&quot; (
	for /f &quot;usebackq tokens=* delims=:&quot; %%s in ( &quot;%~f0&quot; ) do (
		if /i &quot;%%s&quot; == &quot;@echo off&quot; goto :EOF
		if not &quot;%%s&quot; == &quot;0&lt;/*! ::&quot; echo:%%s
	)
	goto :EOF
)

for %%o in ( LIST PROPERTY ) do if /i &quot;%~2&quot; == &quot;/%%~o&quot; (
	cscript //nologo //e:javascript &quot;%~f0&quot; %*
	goto :EOF
)

echo:Executing...
echo:msiexec /quiet /a &quot;%~f1&quot; TARGETDIR=&quot;%~f2&quot;
call msiexec /quiet /a &quot;%~f1&quot; TARGETDIR=&quot;%~f2&quot;

goto :EOF
*/0;

// ========================================================================

try {
	var msiFile = WScript.Arguments.item(0);
	var mode = WScript.Arguments.item(1);
	var msiInfo =
		mode.match(/^\/LIST$/i) ? getMsiListing(msiFile) :
		mode.match(/^\/PROPERTY$/i) ? getMsiProperty(msiFile) :
		&#039;/LIST or /PROPERTY required&#039;;
	WScript.StdOut.WriteLine(msiInfo);
} catch(e) {
	WScript.StdErr.WriteLine(&#039;Cannot probe file: &#039; + msiFile);
	WScript.StdErr.WriteLine(&#039;Error: &#039; + e.message);
	WScript.Quit(1);
}

// ========================================================================

// JS code was adapted from VBS implementation found by these links:
// https://serverfault.com/a/465717/423234
// http://scriptbox.toll.at/index.php?showcontent=Get%20MSI-File%20properties.vbs&amp;list=1
// https://www.hanselman.com/blog/how-to-list-all-the-files-in-an-msi-installer-using-vbsciript

function getMsiListing(filename) {
	return getMsiView(filename, {
		sql: &#039;Select FileSize, FileName From File&#039;,
		header: &#039;FileSize FileName&#039;.split(&#039; &#039;),
		align: function(value, width, padding) {
			return ( padding + value ).slice(-width);
		}
	});
}

function getMsiProperty(filename) {
	return getMsiView(filename, {
		sql: &#039;Select * From Property&#039;,
		header: &#039;Property Value&#039;.split(&#039; &#039;),
		align: function(value, width, padding) {
			return ( value + padding ).slice(0, width);
		}
	});
}

function getMsiView(filename, options) {
	var installer = new ActiveXObject(&#039;WindowsInstaller.Installer&#039;);
	var installerDatabase = installer.OpenDatabase(filename, 0);
	var installerView = installerDatabase.OpenView(options.sql);
	installerView.Execute();

	var installerRecord;

	var r = [];
	var maxLen = 0;

	while ( installerRecord = installerView.Fetch() ) {
		var n = installerRecord.FieldCount;
		var s = [];
		for (var i = 1; i &lt;= n; i++) {
			s.push(installerRecord.StringData(i));
		}
		maxLen = Math.max(maxLen, s[0].length);
		r.push(s);
	}

	var padding = new Array(maxLen + 1).join(&#039; &#039;);

	r.unshift(options.header);

	for (var i = 0; i &lt; r.length; i++) {
		r[i][0] = options.align(r[i][0], maxLen, padding);
		r[i] = r[i].join(&#039; : &#039;);
	}

	return r.join(&#039;\n&#039;);
}

// ========================================================================

// EOF
</code></pre></div></div></div><p>Близкое по содержанию обсуждение уже поднималось мной же здесь: <a href="http://forum.script-coding.com/viewtopic.php?id=12176">Распаковка (не инсталляция) MSI файлов</a></p>]]></summary>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2021-03-28T15:19:49Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=16216&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: uptime]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=14903&amp;action=new" />
			<summary type="html"><![CDATA[<p>По мотивам темы <a href="http://forum.script-coding.com/viewtopic.php?id=14889">VBS: Время работы системы</a> написал скриптик, который почти повторяет работу unix-команды <strong>uptime</strong> -- показывает текущее время и как долго работает система.</p><p>Обсуждение в отдельной теме: <a href="http://forum.script-coding.com/viewtopic.php?id=14901">http://forum.script-coding.com/viewtopic.php?id=14901</a></p><p>Пример:</p><div class="codebox"><pre><code>
C:\&gt;uptime
 08:51:40 up 73 days, 07:57

C:\&gt;
</code></pre></div><p>Исходный код: <a href="https://github.com/ildar-shaimordanov/cmd.scripts/blob/master/uptime.bat">https://github.com/ildar-shaimordanov/c … uptime.bat</a><br />Использовалась идея, почерпнутая из этого ответа на stackoverflow <a href="https://stackoverflow.com/a/11128674/3627676">https://stackoverflow.com/a/11128674/3627676</a></p><div class="codebox"><pre><code>
@echo off

:: ========================================================================

setlocal

set &quot;uptime_boot=&quot;
set &quot;uptime_curr=&quot;

for /f &quot;tokens=1,* delims==&quot; %%a in ( &#039;
	wmic OS GET LastBootUpTime^,LocalDateTime /VALUE
&#039; ) do if /i &quot;%%~a&quot; == &quot;LastBootUpTime&quot; (
	call :get_ts &quot;%%~b&quot; uptime_boot
) else if /i &quot;%%~a&quot; == &quot;LocalDateTime&quot; (
	call :get_ts &quot;%%~b&quot; uptime_curr
)

set /a &quot;uptime_diff=uptime_curr-uptime_boot&quot;

call :get_datetime diff
call :get_datetime curr

echo: %uptime_curr_hh%:%uptime_curr_mm%:%uptime_curr_ss% up %uptime_diff_dd% days, %uptime_diff_hh%:%uptime_diff_mm%

goto :EOF

:: ========================================================================

:get_datetime
set /a &quot;uptime_%~1_ss=uptime_%~1 %% 60&quot;
set /a &quot;uptime_%~1_mm=uptime_%~1 / 60 %% 60&quot;
set /a &quot;uptime_%~1_hh=uptime_%~1 / 60 / 60 %% 24&quot;
set /a &quot;uptime_%~1_dd=uptime_%~1 / 60 / 60 / 24&quot;

call set &quot;uptime_%~1_ss=0%%uptime_%~1_ss%%&quot;
call set &quot;uptime_%~1_mm=0%%uptime_%~1_mm%%&quot;
call set &quot;uptime_%~1_hh=0%%uptime_%~1_hh%%&quot;

call set &quot;uptime_%~1_ss=%%uptime_%~1_ss:~-2%%&quot;
call set &quot;uptime_%~1_mm=%%uptime_%~1_mm:~-2%%&quot;
call set &quot;uptime_%~1_hh=%%uptime_%~1_hh:~-2%%&quot;

goto :EOF

:: ========================================================================

:: Borowed from https://stackoverflow.com/a/11128674/3627676

:: Convert date/time from YYYYMMDDhhmmss.SSSSSS+zzz to Unix timestamp

:: 20190523222121.762088+180
:: 20190801180759.901000+180
::           1         2
:: 0123456789012345678901234

:: Get the timestamp in UTC
:get_ts_utc

:: Get the timestamp in local time
:get_ts
setlocal

set &quot;ts=%~1&quot;

set /a &quot;yy=10000%ts:~0,4% %% 10000, mm=100%ts:~4,2% %% 100, dd=100%ts:~6,2% %% 100&quot;
set /a &quot;dd=dd-2472663+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4&quot;

::set /a ss=(((1%ts:~8,2%*60)+1%ts:~10,2%)*60)+1%ts:~12,2%-366100-%ts:~21,1%((1%ts:~22,3%*60)-60000)
set /a &quot;ss=(((1%ts:~8,2%*60)+1%ts:~10,2%)*60)+1%ts:~12,2%-366100&quot;
if &quot;%~0&quot; == &quot;:get_ts_utc&quot; set /a &quot;ss-=%ts:~21,1%((1%ts:~22,3%*60)-60000)&quot;

set /a ss+=dd*86400

endlocal &amp; if &quot;%~2&quot; neq &quot;&quot; (set %~2=%ss%) else echo %ss%
goto :EOF

:: ========================================================================

:: EOF
</code></pre></div>]]></summary>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2019-08-05T17:22:08Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=14903&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: Различия между .cmd и .bat в Windows]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=14178&amp;action=new" />
			<summary type="html"><![CDATA[<p>Когда-то давно я задался вопросом &quot;в чем разница между этими расширениями в <strong>последних версиях Windows</strong>&quot;. Делаю акцент именно на этом, потому что встречаются весьма частые ответы о том, что <br />-- .bat для COMMAND.COM, а .cmd для CMD.EXE<br />-- .bat это в Windows, а .cmd - это в OS/2</p><p>Все это далеко от ответов на поставленный вопрос. А ответ есть - <a href="https://stackoverflow.com/a/148991/3627676">https://stackoverflow.com/a/148991/3627676</a>: </p><div class="quotebox"><blockquote><p>The differences between .CMD and .BAT as far as CMD.EXE is concerned are: With extensions enabled, PATH/APPEND/PROMPT/SET/ASSOC in .CMD files will set ERRORLEVEL regardless of error. .BAT sets ERRORLEVEL only on errors.</p></blockquote></div><p>Авторский перевод<br /></p><div class="quotebox"><blockquote><p>Различия между .CMD и .BAT в CMD.EXE следующие: при включенной опции ENABLEEXTENSIONS, встроенные команды PATH/APPEND/PROMPT/SET/ASSOC в .CMD файлах выставляют собственный код ошибки в ERRORLEVEL независимо от ошибки. .BAT файлы выставляют код ошибки в ERRORLEVEL только в случае ошибки.</p></blockquote></div><p>Проиллюстрирую сказанное простым примером -- скрипт вызывает несуществующую команду (естественно, не находит ее) и печатает строку подсказки. После первой команды выставляется код ошибки 9009, который мы отображаем сразу после вызова и после встроенной команды<br /></p><div class="codebox"><pre><code>
@echo off

non-existing-command
echo:After wrong command  : %errorlevel%

prompt
echo:After prompt command : %errorlevel%
</code></pre></div><p>Вывод <strong>.bat</strong> файла: команда <strong>prompt</strong> оказалась &quot;прозрачной&quot; для <strong>%ERRORLEVEL%</strong><br /></p><div class="codebox"><pre><code>
&#039;non-existing-command&#039; is not recognized as an internal or external command,
operable program or batch file.
After wrong command  : 9009
After prompt command : 9009
</code></pre></div><p>Вывод <strong>.cmd</strong> файла: здесь очевидно, что команда вернула свой код ошбки (ноль) и затерла код ошибки предыдущей команды<br /></p><div class="codebox"><pre><code>
&#039;non-existing-command&#039; is not recognized as an internal or external command,
operable program or batch file.
After wrong command  : 9009
After prompt command : 0
</code></pre></div><p>Различия незначительные, но могут попортить нервов на поиски решения проблемы в случае скрипта, аналогичном примеру. Этот пример лишний раз говорит в пользу первичной инициализации состояния и переменных.</p><p>P.S.</p><p>Посмотрел описание команд -- туманно и рекурсивно (сепульки и сепулькарии), а про код ошибки - ни слова. </p><div class="quotebox"><cite>setlocal /? пишет:</cite><blockquote><div class="codebox"><pre><code>
. . . 
        ENABLEEXTENSIONS / DISABLEEXTENSIONS
            enable or disable command processor extensions. These
            arguments takes precedence over the CMD /E:ON or /E:OFF
            switches. See CMD /? for details.
. . .
</code></pre></div></blockquote></div><div class="quotebox"><cite>cmd /? пишет:</cite><blockquote><div class="codebox"><pre><code>
. . . 
See SETLOCAL /? for details.
. . . 
To get specific details, type commandname /? to view the specifics.
</code></pre></div></blockquote></div><div class="quotebox"><cite>prompt /? пишет:</cite><blockquote><div class="codebox"><pre><code>
Changes the cmd.exe command prompt.
. . . 
If Command Extensions are enabled the PROMPT command supports
the following additional formatting characters:
. . . 
</code></pre></div></blockquote></div>]]></summary>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2018-09-20T03:24:05Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=14178&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: Перенаправление вывода в GUI]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=12113&amp;action=new" />
			<summary type="html"><![CDATA[<p>Скрипт для показа вывода консольной команды в GUI приложении. По сути, это многословная, гибкая и конфигурируемая обертка вокруг пары команд:<br /></p><div class="codebox"><pre><code>
команда &gt; &quot;временный-файл&quot;
приложение &quot;временный-файл&quot;
</code></pre></div><p>У меня есть некоторое приложение, которое генерирует HTML из некоторых данных. Надо было его посмотреть в браузере. И я не хотел заботиться о создании/хранении/удалении временного файла. В результате я однажды написал что-то такое простенькое. Потом его улучшил. Через какое-то время еще раз улучшил, а потом переписал в то, что получилось. </p><p><strong>Применение</strong></p><p>Показать в Блокноте<br /></p><div class="codebox"><pre><code>
команда | 2
</code></pre></div><p>Показать в браузере (например, Internet Explorer)<br /></p><div class="codebox"><pre><code>
команда | 2 html
</code></pre></div><p>Насторить показ в другом приложении (например, Firefox) с помощью вспомогательного файла 2.html.bat<br /></p><div class="codebox"><pre><code>
set &quot;pipecmd=%ProgramFiles%\Firefox\firefox.exe&quot;
</code></pre></div><p>Изменить способ отображения &quot;на лету&quot; (например, HTML показать как текст)<br /></p><div class="codebox"><pre><code>
команда | 2 html.txt
</code></pre></div><p><strong>Специальные возможности</strong><br /></p><div class="codebox"><pre><code>
-d DIR     использовать каталог DIR для временных файлов
-n NAME    использовать NAME как имя временного файла
--debug    включить отладку (показ переменных окружения)
--dry-run  &quot;сухой&quot; запуск, показать команды, как если бы они выполнились
</code></pre></div><p><strong>Переменные окружения</strong></p><p>%pipecmd%</p><p>(обязательный)<br />строка запуска приложения (может содержать дополнительные аргументы</p><p>%pipeext%</p><p>(опционально, но рекомендуется установить)<br />расширение (строка вида &quot;.txt&quot;, &quot;.html&quot; и т.д.) необходима для распознавания формата вывода. </p><p>%pipetmpsave%</p><p>(необязательный)<br />команда, используемая для сохранения потока во временнный файл. По умолчанию это команда &quot;more&quot;. </p><p><strong>Исходный код</strong></p><p><a href="https://github.com/ildar-shaimordanov/cmd.scripts/blob/master/bin/2.bat">https://github.com/ildar-shaimordanov/c … /bin/2.bat</a><br /><a href="https://github.com/ildar-shaimordanov/cmd.scripts/blob/master/bin/2.html.bat">https://github.com/ildar-shaimordanov/c … 2.html.bat</a></p><div class="codebox"><pre><code>
::HELP Redirects output of command line tools to GUI application.
::HELP
::HELP
::HELP USAGE
::HELP
::HELP command | 2 [OPTIONS] [APP[.EXT] | EXT] [APP-OPTIONS]
::HELP
::HELP
::HELP OPTIONS
::HELP
::HELP -d DIR     use DIR for storing temp files
::HELP -n NAME    use NAME as the name of temp file
::HELP --debug    turn on debug information
::HELP --dry-run  don&#039;t invoke a command, display only
::HELP
::HELP
::HELP DESCRIPTION
::HELP
::HELP The script is flexible enough to enable many ways to invoke GUI 
::HELP applications. Which GUI application would be invoked is defined by 
::HELP the arguments. Depending on what is this, it will be called to 
::HELP declare few specific environment variables. 
::HELP
::HELP
::HELP INVOCATION
::HELP
::HELP commands | 2
::HELP
::HELP With no parameters runs Notepad. Always. 
::HELP
::HELP commands | 2 APP
::HELP
::HELP &quot;APP&quot; is the parameter defining an application or a family of 
::HELP applications or an extension (without the leading &quot;dot&quot; symbol). 
::HELP The script looks around for the file called as &quot;2.APP.bat&quot;. If the 
::HELP file exists, invokes it to set the needful environment variables. 
::HELP The script should declare few specific environment variables (see 
::HELP the &quot;ENVIRONMENT&quot; section below). 
::HELP
::HELP commands | 2 APP.EXT
::HELP
::HELP The same as above but &quot;.EXT&quot; overrides early declared extension. 
::HELP
::HELP commands | 2 EXT
::HELP
::HELP If there is no file &quot;2.APP.bat&quot;, the argument is assumed as the 
::HELP extension (without the leading &quot;dor&quot; symbol), the script does 
::HELP attempt to find an executable command (using &quot;assoc&quot; and &quot;ftype&quot;) 
::HELP and prepare invocation of the command found by these commands. 
::HELP
::HELP
::HELP ENVIRONMENT
::HELP
::HELP %pipecmd%
::HELP
::HELP (Mandatory)
::HELP Invocation string for the application. It could or could not 
::HELP contain additional parameters supported by the application. 
::HELP
::HELP %pipeext%
::HELP
::HELP (Optional, but recommended to set)
::HELP Extenstion (like &quot;.txt&quot; or &quot;.html&quot; etc). It can be useful in the 
::HELP case if the application is able to handle different data files. 
::HELP
::HELP %pipetmpsave%
::HELP
::HELP (Optional)
::HELP The command line tool used for capturing output of commands and 
::HELP redirecting to a resulting file. By default it is set as follows: 
::HELP
::HELP set &quot;pipetmpsave=more&quot;
::HELP
::HELP Another possible setting is:
::HELP
::HELP set &quot;pipetmpsave=findstr &quot;$&quot;&quot;
::HELP
::HELP
::HELP CONFIGURATION
::HELP
::HELP Using the file &quot;2-settings.bat&quot; located in the same directory 
::HELP allows to configure the global environment variables of the main 
::HELP script. It is good place for setting such kind of variables as 
::HELP %pipetmpdir%, %pipetmpname% and %pipetmpsave%. 
::HELP
::HELP
::HELP SEE ALSO
::HELP
::HELP ASSOC /?
::HELP FTYPE /?

:: ========================================================================

@echo off

timeout /t 0 &gt;nul 2&gt;&amp;1 &amp;&amp; (
	call :pipe-help
	goto :EOF
)

:: ========================================================================

setlocal

set &quot;pipedbg=&quot;
set &quot;pipedry=&quot;

set &quot;pipetmpdir=%TEMP%&quot;
set &quot;pipetmpname=pipe.%RANDOM%&quot;
set &quot;pipetmpfile=&quot;
set &quot;pipetmpsave=more&quot;

if exist &quot;%~dpn0-settings.bat&quot; call &quot;%~dpn0-settings.bat&quot;

set &quot;pipecmd=&quot;
set &quot;pipecmdopts=&quot;
set &quot;pipetitle=&quot;
set &quot;pipeext=&quot;

:: ========================================================================

:pipe-options-begin

if &quot;%~1&quot; == &quot;&quot; goto :pipe-options-end

if &quot;%~1&quot; == &quot;-d&quot; (
	set &quot;pipetmpdir=%~2&quot;
	shift /1
	shift /1
) else if &quot;%~1&quot; == &quot;-n&quot; (
	set &quot;pipetmpname=%~2&quot;
	shift /1
	shift /1
) else if &quot;%~1&quot; == &quot;--debug&quot; (
	set &quot;pipedbg=1&quot;
	shift /1
) else if &quot;%~1&quot; == &quot;--dry-run&quot; (
	set &quot;pipedry=1&quot;
	shift /1
) else (
	goto :pipe-options-end
)

goto :pipe-options-begin
:pipe-options-end

:: ========================================================================

if &quot;%~1&quot; == &quot;&quot; (

	rem command | 2

	set &quot;pipecmd=notepad&quot;
	set &quot;pipetitle=[app = notepad]&quot;
	set &quot;pipeext=.txt&quot;

) else if exist &quot;%~dpn0.%~n1.bat&quot; (

	rem command | 2 app[.ext]

	call :pipe-configure &quot;%~dpn0.%~n1.bat&quot; &quot;%~x1&quot;

	set &quot;pipetitle=[app = %~n1]&quot;
	if not defined pipeext set &quot;pipeext=%~n1&quot;
	if not &quot;%~x1&quot; == &quot;&quot; set &quot;pipeext=%~x1&quot;

	shift /1

) else (

	rem command | 2 ext

	for /f &quot;tokens=1,* delims==&quot; %%a in ( &#039;
		2^&gt;nul assoc &quot;.%~n1&quot;
	&#039; ) do for /f &quot;tokens=1,* delims==&quot; %%c in ( &#039;
		2^&gt;nul ftype &quot;%%b&quot;
	&#039; ) do (

		set &quot;pipecmd=%%d&quot;
		set &quot;pipetitle=[%%a = %%b]&quot;
		set &quot;pipeext=%%a&quot;

	)
	if not &quot;%~x1&quot; == &quot;&quot; set &quot;pipeext=%~x1&quot;

	shift /1

)

if defined pipedbg call :pipe-debug &quot;After parsing options&quot;

:: ========================================================================

if not defined pipecmd (
	&gt;&amp;2 echo:Bad invocation
	goto :EOF
)

:: ========================================================================

if not defined pipeext set &quot;pipeext=.txt&quot;
if not defined pipetitle set &quot;pipetitle=[%pipeext%]&quot;

for %%f in ( &quot;%pipetmpdir%&quot; ) do set &quot;pipetmpfile=%%~ff\%pipetmpname%%pipeext%&quot;

:: ========================================================================

setlocal enabledelayedexpansion

set &quot;pipecmdopt=&quot;

:pipe-app-options-begin
set pipecmdopt=%1
if not defined pipecmdopt goto :pipe-app-options-end

set &quot;pipecmdopts=%pipecmdopts% %pipecmdopt%&quot;
shift /1

goto :pipe-app-options-begin
:pipe-app-options-end

set &quot;pipecmd=!pipecmd:%%1=&quot;%%1&quot;!&quot;
set &quot;pipecmd=!pipecmd:&quot;&quot;%%1&quot;&quot;=&quot;%%1&quot;!&quot;
if &quot;!pipecmd!&quot; == &quot;!pipecmd:%%1=!&quot; set &quot;pipecmd=!pipecmd! &quot;%%1&quot;&quot;
set &quot;pipecmd=!pipecmd:%%1=%pipetmpfile%!&quot;

endlocal &amp; set &quot;pipecmd=%pipecmd%&quot; &amp; set &quot;pipecmdopts=%pipecmdopts%&quot;

:: ========================================================================

if defined pipedbg call :pipe-debug &quot;Before invocation&quot;

call :pipe-invoke %pipecmdopts%

endlocal
goto :EOF

:: ========================================================================

:pipe-configure
setlocal
call &quot;%~1&quot; &quot;%~2&quot;
endlocal &amp; set &quot;pipecmd=%pipecmd%&quot; &amp; set &quot;pipeext=%pipeext%&quot; &amp; set &quot;pipetmpsave=%pipetmpsave%&quot;
goto :EOF

:pipe-invoke
if defined pipedry (
	echo:Invocation ^(dry-run^)
	echo:call %pipetmpsave% ^&gt; &quot;%pipetmpfile%&quot;
	echo:call start &quot;Starting %pipetitle%&quot; %pipecmd%
	goto :EOF
)

call %pipetmpsave% &gt; &quot;%pipetmpfile%&quot;
call start &quot;Starting %pipetitle%&quot; %pipecmd%
goto :EOF

:: ========================================================================

:pipe-help
for /f &quot;tokens=1,* delims= &quot; %%a in ( &#039;
	findstr /b &quot;::HELP&quot; &quot;%~f0&quot;
&#039; ) do (
	echo:%%~b
)
goto :EOF

:pipe-debug
echo:%~1...
set pipe
echo:
goto :EOF

:: ========================================================================

:: EOF
</code></pre></div>]]></summary>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2016-10-29T22:48:16Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=12113&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: Скрипт создания скриптов по принципу "два в одном"]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=10114&amp;action=new" />
			<summary type="html"><![CDATA[<p>Скрипт создания скриптов по принципу &quot;два в одном&quot;. Обсуждение <a href="https://forum.script-coding.com/viewtopic.php?id=16685">здесь</a>.</p><p>Такие скрипты еще называют &quot;<strong>гибридами</strong>&quot;, потому что они совмещают в себе батник и другой язык таким образом, что он будет выполнятся как в CMD, так и другим интерпретатором.</p><p>Я бы ввел еще понятие &quot;<strong>химера</strong>&quot;. Химера отличается от гибрида тем, что для полноценного запуска химеры требуются дополнительные настройки (например, временные файлы, переменные окружения, недокументированные возможности или трюки).</p><p><strong>Пример работы</strong></p><p>создать filename1.bat и filename2.bat из исходных файлов</p><div class="codebox"><pre><code>
cmdize.bat filename1.vbs filename2.js
</code></pre></div><p>показать список поддерживаемых типов файлов и опций командной строки, доступных для каждого типа:</p><div class="codebox"><pre><code>
cmdize.bat /L
</code></pre></div><p><strong>Очень краткая справка</strong></p><div class="codebox"><pre><code>
&gt;cmdize
Converts a script into a batch file.

# USAGE

    cmdize /HELP | /HELP-MORE | /HELP-DEVEL
    cmdize /L
    cmdize [/W] [/E engine] [/P] file ...

# OPTIONS

* `/HELP` - Show this help and description.
* `/HELP-MORE` - Show more details.
* `/HELP-DEVEL` - Show extremely detailed help including internal details.
* `/L` - Show the list of supported file extensions and applicable options.
* `/E` - Set an engine for using as a the script runner.
* `/W` - Set the alternative engine (for VBScript only).
* `/P` - Display on standard output instead of creating a new file.
</code></pre></div><p><strong>Полный список поддерживаемых языков и технологий</strong><br />-- JavaScript<br />-- VBScript<br />-- Perl<br />-- Shell/Bash<br />-- PowerShell<br />-- Python<br />-- Ruby<br />-- HTA<br />-- HTML<br />-- WSF<br />-- KixStart<br />-- AutoIt, AutoHotKey<br />-- PHP<br />-- Julia</p><p>Предлагаемый скрипт <strong>cmdize.bat</strong> конвертирует оригинальный файл в пакетный, добавляя в начале каждого файла специальный заголовок-&quot;полиглот&quot;, фрагмент кода, синтаксически корректный как в BAT, так и во внедряемом скрипте. В основном, это часть кода, являющаяся комментарием для основного скрипта, использующая некоторые ухищрения для BAT-файла. </p><p><strong>Особенности</strong></p><p>Для VBS-скрипта дополнительно проверяется наличие директивы <em>Option Explicit</em>, которая &quot;прячется&quot; в комментариях, так как во вновь созданном файле она перестает быть первой исполняемой командой и бросает ошибку компиляции. Хотя наличие этой директивы желательно и даже обязательно (как правильно сказал коллега <strong>alexii</strong> <a href="http://forum.script-coding.com/viewtopic.php?pid=87220#p87220">о правильном стиле программирования</a>), но это требование можно (в данном случае) смягчить в угоду удобству. Предполагается, что исходный vbs-код тщательно отлажен с включенной директивой. <em>Директива должна быть записана в одну строку. Разбиение на несколько строк не поддерживается. </em></p><p>В wsf-файлах используется весьма странная конструкция <em>%~f0?.wsf</em>, которая позволяет запускать bat-файл как wsf-сценарий. Возможно это какая-то недокументированная особенность парсера командной строки. А может быть это <a href="http://www.dostips.com/forum/viewtopic.php?p=34003#p34003">бэкдор</a>. </p><p>wsf-файл может начинаться с директивы <em>&lt;?xml?&gt;</em>. <em>Чтобы утилита распознала директиву, она должна быть записана в одну строку. Разбиение на несколько строк не поддерживается. </em></p><p>Скрипт не понимает BOM. </p><p>Есть возможность выбрать движок для JavaScript, VBScript и WSF с помощью опции /E. Если не укаано явно, то CSCRIPT - движок по умолчанию для JavaScript, VBScript и WSF скриптов. Другое доступное значение - WSCRIPT. Дополнительно для JavaScript файлов можно выбрать другой движок, например, NodeJS, Rhino и т.д. Предопределенная опция /E DEFAULT сбрасывает ранее установленный движок в значение по умолчанию. </p><p><strong>Компиляция известных решений</strong></p><p><a href="http://forum.script-coding.com/viewtopic.php?pid=79210#p79210">CMD/BAT + JavaScript: два в одном</a><br /><a href="http://forum.script-coding.com/viewtopic.php?id=6304">JScript:CMD - вариант с условной компиляцией</a></p><p><a href="http://forum.script-coding.com/viewtopic.php?pid=82089#p82089">CMD/BAT + VBScript: два в одном</a><br /><a href="http://forum.script-coding.com/viewtopic.php?id=8742">CMD/BAT + HTML: два в одном</a></p><p>А также:<br /><a href="http://stackoverflow.com/a/2611487/3627676">PowerShell в BAT на StackOverflow</a><br /><a href="http://www.dostips.com/forum/viewtopic.php?p=33963#p33963">WSF в BAT</a> (забугорный форум, специализирующийся на пакетных файлах; в теме перекрестные ссылки с нашим форумом)</p><p><strong>Исходный код</strong></p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;исходный код cmdize.bat</div><div class="fancy_spoiler"><p>Скопировать и сохранить в <strong>cmdize.bat</strong>. <br />Актуальная версия <a href="https://github.com/ildar-shaimordanov/cmd.scripts/blob/master/cmdize.bat">здесь</a>. </p><div class="codebox"><pre><code>
::U&gt;Converts a script into a batch file.
::U&gt;
::U&gt;# USAGE
::U&gt;
::U&gt;    cmdize /HELP | /HELP-MORE | /HELP-DEVEL
::U&gt;    cmdize /L
::U&gt;    cmdize [/W] [/E engine] [/P] file ...
::U&gt;
::U&gt;# OPTIONS
::U&gt;
::U&gt;* `/HELP` - Show this help and description.
::U&gt;* `/HELP-MORE` - Show more details.
::U&gt;* `/HELP-DEVEL` - Show extremely detailed help including internal details.
::U&gt;* `/L` - Show the list of supported file extensions and applicable options.
::U&gt;* `/E` - Set an engine for using as a the script runner.
::U&gt;* `/W` - Set the alternative engine (for VBScript only).
::U&gt;* `/P` - Display on standard output instead of creating a new file.
::U&gt;

::H&gt;# DESCRIPTION
::H&gt;
::H&gt;This tool converts a script into a batch file allowing to use the script like regular programs and batch scripts without invoking an executable engine explicitly and just typing the script name without extension. The resulting batch file is placed next to the original script.
::H&gt;
::H&gt;The new file consist of the body of the script prepended with the special header (or prolog) being the *polyglot* and having some tricks to be a valid code both for the batch and original script.
::H&gt;
::H&gt;This tool is pure batch file. So there is limitation in processing files having Byte Order Mark (BOM). For example, it fail with high probability while processing a unicode encoded WSF-file with XML declaration.
::H&gt;
::H&gt;The *engine* term stands for the executable running the script. Not for all languages it&#039;s applicable. Depending the language, the engine can be set to any, none or one of predefined values. `/E DEFAULT` is the special engine that resets any previously set engines to the default value. The same result can be received with `/E &quot;&quot;`.
::H&gt;
::H&gt;For WSF-scripts the engine is one of `CSCRIPT` and `WSCRIPT`. If XML declaration is presented (in the form like `&lt;?xml...?&gt;`), it must be in the most beginning of the file. Otherwise error is reported and the script is not cmdized.
::H&gt;
::H&gt;For JavaScript/JScript it can be one of `CSCRIPT`, `WSCRIPT` (for JScript5+), `CCHAKRA`, `WCHAKRA` (for JScript9 or Chakra) or any valid command with options to enable running NodeJS, ChakraCore, Rhino and so on (for example, `node`, `ch`, `java -jar rhino.jar`, respectively).
::H&gt;
::H&gt;For VBScript there is choice from either `CSCRIPT` or `WSCRIPT`. If the script implements the statement `Option Explicit`, then it is commented to avoid the compilation error. The `/W` option creates the alternative runner embedding the script into a WSF-file. In this case that statement is not commented and left as is.
::H&gt;
::H&gt;For Perl `/E CMDONLY` is the only applicable value. It&#039;s fake engine that is used for creating the pure batch file for putting it with the original script in PATH.
::H&gt;
::H&gt;For Python `/E SHORT` specifies creation of a quite minimalistic runner file. Other values don&#039;t make sense.
::H&gt;
::H&gt;# AUTHORS and CONTRIBUTORS
::H&gt;
::H&gt;Ildar Shaimordanov is the main author maintaining the tool since 2014. First steps in this direction were made in 2009, when he created the `js2bat` script. Some stuff is invented by him, other is collected from different sources in the Internet.
::H&gt;
::H&gt;leo-liar (https://github.com/leo-liar) pointed on and provided the fix for the potential problem when some users who have UNIX tools in their PATH might call a different FIND.EXE which will break this script.
::H&gt;
::H&gt;greg zakharov (https://forum.script-coding.com/profile.php?id=27367) disputes and throws interesting ideas time to time.
::H&gt;
::H&gt;Residents of the forum https://www.dostips.com/forum/ with whom the author has opportunity to discuss many aspects of batch scripting.
::H&gt;
::H&gt;# SEE ALSO
::H&gt;
::H&gt;Find this text and more details following by this link below.
::H&gt;
::H&gt;https://github.com/ildar-shaimordanov/cmd.scripts/blob/master/doc/cmdize.md
::H&gt;
::H&gt;Tests are here:
::H&gt;
::H&gt;https://github.com/ildar-shaimordanov/cmd.scripts/tree/master/t
::H&gt;

@echo off

if &quot;%~1&quot; == &quot;&quot; (
	call :print-usage U
	goto :EOF
)

if /i &quot;%~1&quot; == &quot;/HELP&quot; (
	call :print-usage UH
	goto :EOF
)

if /i &quot;%~1&quot; == &quot;/HELP-MORE&quot; (
	call :print-usage UHD
	goto :EOF
)

if /i &quot;%~1&quot; == &quot;/HELP-DEVEL&quot; (
	call :print-usage UHDG
	goto :EOF
)

if /i &quot;%~1&quot; == &quot;/L&quot; (
	call :print-extension-list
	goto :EOF
)

setlocal

set &quot;CMDIZE_ERROR=0&quot;
set &quot;CMDIZE_WRAP=&quot;
set &quot;CMDIZE_ENGINE=&quot;
set &quot;CMDIZE_MAYBE=&gt;&quot;

:cmdize_loop_begin
if &quot;%~1&quot; == &quot;&quot; exit /b %CMDIZE_ERROR%

if /i &quot;%~1&quot; == &quot;/W&quot; (
	set &quot;CMDIZE_WRAP=1&quot;
	shift /1
	goto :cmdize_loop_begin
)

if /i &quot;%~1&quot; == &quot;/E&quot; (
	if /i &quot;%~2&quot; == &quot;default&quot; (
		set &quot;CMDIZE_ENGINE=&quot;
	) else (
		set &quot;CMDIZE_ENGINE=%~2&quot;
	)
	shift /1
	shift /1
	goto :cmdize_loop_begin
)

if /i &quot;%~1&quot; == &quot;/P&quot; (
	set &quot;CMDIZE_MAYBE=&amp; rem &quot;
	shift /1
	goto :cmdize_loop_begin
)

if not exist &quot;%~f1&quot; (
	set &quot;CMDIZE_ERROR=1&quot;
	call :warn File not found: &quot;%~1&quot;
	shift /1
	goto :cmdize_loop_begin
)

findstr /i /b /l &quot;:cmdize%~x1&quot; &quot;%~f0&quot; &gt;nul || (
	set &quot;CMDIZE_ERROR=1&quot;
	call :warn Unsupported extension: &quot;%~1&quot;
	shift /1
	goto :cmdize_loop_begin
)

call :cmdize%~x1 &quot;%~1&quot; %CMDIZE_MAYBE% &quot;%~dpn1.bat&quot;
shift /1
goto :cmdize_loop_begin

:: ========================================================================

::D&gt;# DETAILS
::D&gt;
::D&gt;More description, more links, more details about implementation in this section.
::D&gt;

::D&gt;## .js
::D&gt;
::D&gt;* `/E CSCRIPT` for `cscript //nologo //e:javascript` (default)
::D&gt;* `/E WSCRIPT` for `wscript //nologo //e:javascript`
::D&gt;* `/E CCHAKRA` for `cscript //nologo //e:{16d51579-a30b-4c8b-a276-0ff4dc41e755}`
::D&gt;* `/E WCHAKRA` for `wscript //nologo //e:{16d51579-a30b-4c8b-a276-0ff4dc41e755}`
::D&gt;
::D&gt;Unfortunately, no easy way to wrap JScript9 into WSF.
::D&gt;
::D&gt;* http://forum.script-coding.com/viewtopic.php?pid=79210#p79210
::D&gt;* http://www.dostips.com/forum/viewtopic.php?p=33879#p33879
::D&gt;* https://gist.github.com/ildar-shaimordanov/88d7a5544c0eeacaa3bc
::D&gt;
::D&gt;The following two links show my first steps in direction to create this script.
::D&gt;
::D&gt;* https://with-love-from-siberia.blogspot.com/2009/07/js2bat-converter.html
::D&gt;* https://with-love-from-siberia.blogspot.com/2009/07/js2bat-converter-2.html
::D&gt;
:cmdize.js	[/e cscript|wscript|cchakra|wchakra|ch|node|...]
if not defined CMDIZE_ENGINE set &quot;CMDIZE_ENGINE=cscript&quot;

for %%e in ( &quot;%CMDIZE_ENGINE%&quot; ) do for %%s in (
	&quot;cscript cscript javascript&quot;
	&quot;wscript wscript javascript&quot;
	&quot;cchakra cscript {16d51579-a30b-4c8b-a276-0ff4dc41e755}&quot;
	&quot;wchakra wscript {16d51579-a30b-4c8b-a276-0ff4dc41e755}&quot;
) do for /f &quot;tokens=1,2,3&quot; %%a in ( &quot;%%~s&quot; ) do if &quot;%%~e&quot; == &quot;%%~a&quot; (
	call :print-prolog &quot;%%~b //nologo //e:%%~c&quot; &quot;0&lt;/*! ::&quot; &quot;*/0;&quot;
	type &quot;%~f1&quot;
)

goto :EOF

:: ========================================================================

::D&gt;## .vbs
::D&gt;
::D&gt;Pure VBScript within a batch file:
::D&gt;
::D&gt;* `/E CSCRIPT` for `cscript //nologo //e:vbscript` (default)
::D&gt;* `/E WSCRIPT` for `wscript //nologo //e:vbscript`
::D&gt;
::D&gt;With `/W` it&#039;s WSF within a batch file (with some specialties for WSF):
::D&gt;
::D&gt;* `/E CSCRIPT` for `cscript //nologo` (default)
::D&gt;* `/E WSCRIPT` for `wscript //nologo`
::D&gt;
::D&gt;* http://www.dostips.com/forum/viewtopic.php?p=33882#p33882
::D&gt;* http://www.dostips.com/forum/viewtopic.php?p=32485#p32485
::D&gt;
:cmdize.vbs	[/w] [/e cscript|wscript]
if not defined CMDIZE_ENGINE set &quot;CMDIZE_ENGINE=cscript&quot;

if defined CMDIZE_WRAP (
	call :print-script-wsf-bat &quot;%~f1&quot; vbscript
	goto :EOF
)

copy /y nul + nul /a &quot;%TEMP%\%~n0.$$&quot; /a 1&gt;nul
for /f &quot;usebackq&quot; %%s in ( &quot;%TEMP%\%~n0.$$&quot; ) do (
	call :print-prolog &quot;%CMDIZE_ENGINE% //nologo //e:vbscript&quot; &quot;&quot; &quot;&quot; &quot;::&#039;%%~s&quot;
)
del /q &quot;%TEMP%\%~n0.$$&quot;

for /f &quot;tokens=1,* delims=:&quot; %%r in ( &#039;findstr /n /r &quot;^&quot; &quot;%~f1&quot;&#039; ) do (
	rem Filtering and commenting &quot;Option Explicit&quot;.

	rem Weird and insane attempt to implement it using capabilities
	rem of batch scripting only.

	rem This ugly code tries as much as it can to recognize and
	rem comment out this directive. It&#039;s flexible enough to find
	rem the directive even the string contains an arbitrary amount
	rem of whitespaces. It fails if both &quot;Option&quot; and &quot;Explicit&quot;
	rem are located on different lines. But it&#039;s too hard to imagine
	rem that someone practices such a strange coding style.

	rem In the other hand, it still tries to recognize the rest of
	rem the line after the directive and put it to the next line,
	rem if it contains an executable code.

	if &quot;%%s&quot; == &quot;&quot; (
		echo:%%s
	) else for /f &quot;tokens=1,*&quot; %%a in ( &quot;%%s&quot; ) do if /i not &quot;%%a&quot; == &quot;Option&quot; (
		echo:%%s
	) else for /f &quot;tokens=1,* delims=&#039;:	 &quot; %%i in ( &quot;%%b&quot; ) do if /i not &quot;%%i&quot; == &quot;Explicit&quot; (
		echo:%%s
	) else (
		call :warn Commenting &quot;Option Explicit&quot; in &quot;%~1&quot;
		echo:rem To avoid compilation error due to embedding into a batch file,
		echo:rem the following line was commented out automatically.
		set /p &quot;=rem &quot; &lt;nul

		if /i &quot;%%b&quot; == &quot;Explicit&quot; (
			rem Option Explicit
			echo:%%s
		) else for /f &quot;tokens=1,* delims=&#039;&quot; %%i in ( &quot;%%b&quot; ) do if /i &quot;%%i&quot; == &quot;Explicit&quot; (
			rem Option Explicit {QUOTE} ...
			echo:%%s
		) else for /f &quot;tokens=1,* delims=:	 &quot; %%i in ( &quot;%%b&quot; ) do if /i &quot;%%i&quot; == &quot;Explicit&quot; (
			rem Option Explicit {COLON|TAB|SPACE} ...
			echo:%%a %%i
			echo:%%j
		)
	)
)
goto :EOF

:: ========================================================================

::D&gt;## .pl
::D&gt;
::D&gt;The document below gives more details about `pl2bat.bat` and `runperl.bat`. In fact, those scripts are full-featured prototypes for this script. By default it acts as the first one but without supporting old DOSs. With the `/E CMDONLY` option it creates the tiny batch acting similar to `runperl.bat`.
::D&gt;
::D&gt;* https://perldoc.perl.org/perlwin32
::D&gt;
:cmdize.pl	[/e cmdonly]
if /i &quot;%CMDIZE_ENGINE%&quot; == &quot;cmdonly&quot; (
	call :print-prolog &quot;perl -x -S&quot; &quot;&quot; &quot;&quot; &quot;@&quot; &quot;dpn0.pl&quot;
	goto :EOF
)

call :print-prolog &quot;perl -x -S&quot; &quot;@rem = &#039;--*-Perl-*--&quot; &quot;@rem &#039;;&quot;
echo:#!perl
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .sh, .bash
::D&gt;
::D&gt;* http://forum.script-coding.com/viewtopic.php?id=11535
::D&gt;* http://www.dostips.com/forum/viewtopic.php?f=3&amp;t=7110#p46654
::D&gt;
:cmdize.sh
:cmdize.bash
call :print-prolog bash &quot;: &lt;&lt; &#039;____CMD____&#039;&quot; &quot;____CMD____&quot;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .ps1
::D&gt;
::D&gt;Very-very-very complicated case. It&#039;s impossible to implement a pure hybrid. And too hard to implement a chimera. The resulting batch stores its filename and passed arguments in two environment variables `PS1_FILE` and `PS1_ARGS`, respectively. Then it invokes powershell which tries to restore arguments, reads the file and invokes it. Also it is powered to continue working with STDIN properly. Powershell has two (at least known for me) ways to invoke another code: Invoke-Expression and invoke ScriptBlock. Both have their advandages and disadvantages. By default, Invoke-Expression is used. To give the users a choice between both, non-empty value in `PS1_ISB` enables ScriptBlock invocation.
::D&gt;
::D&gt;* http://blogs.msdn.com/b/jaybaz_ms/archive/2007/04/26/powershell-polyglot.aspx
::D&gt;* http://stackoverflow.com/a/2611487/3627676
::D&gt;
:cmdize.ps1
echo:^&lt;# :
echo:@echo off
echo:setlocal
echo:rem Any non-empty value changes the script invocation: the script is
echo:rem executed using ScriptBlock instead of Invoke-Expression as default.
echo:set &quot;PS1_ISB=&quot;
echo:set &quot;PS1_FILE=%%~f0&quot;
echo:set &quot;PS1_ARGS=%%*&quot;
echo:powershell -NoLogo -NoProfile -Command &quot;$a=($Env:PS1_ARGS|sls -Pattern &#039;\&quot;(.*?)\&quot;(?=\s|$)|(\S+)&#039; -AllMatches).Matches;$a=@(@(if($a.count){$a})|%%%%{$_.value -Replace &#039;^\&quot;&#039;,&#039;&#039; -Replace &#039;\&quot;$&#039;,&#039;&#039;});$f=gc $Env:PS1_FILE -Raw;if($Env:PS1_ISB){$input|&amp;{[ScriptBlock]::Create(&#039;rv f,a -Scope Script;&#039;+$f).Invoke($a)}}else{$i=$input;iex $(&#039;$input=$i;$args=$a;rv i,f,a;&#039;+$f)}&quot;
echo:goto :EOF
echo:#^&gt;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .py
::D&gt;
::D&gt;* http://stackoverflow.com/a/29881143/3627676
::D&gt;* http://stackoverflow.com/a/17468811/3627676
::D&gt;
:cmdize.py	[/e short]
if /i &quot;%CMDIZE_ENGINE%&quot; == &quot;short&quot; (
	call :print-prolog &quot;python -x&quot; &quot;&quot; &quot;&quot; &quot;@&quot; &quot;f0&quot;
	type &quot;%~f1&quot;
	goto :EOF
)
echo:0^&lt;0# : ^^
call :print-prolog python &quot;&#039;&#039;&#039;&quot; &quot;&#039;&#039;&#039;&quot;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .rb
::D&gt;
::D&gt;* https://stackoverflow.com/questions/35094778
::D&gt;
:cmdize.rb
echo:@break #^^
call :print-prolog ruby &quot;=begin&quot; &quot;=end&quot;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .hta, .htm, .html
::D&gt;
::D&gt;* http://forum.script-coding.com/viewtopic.php?pid=79322#p79322
::D&gt;
:cmdize.hta
:cmdize.htm
:cmdize.html
call :print-prolog &quot;start mshta&quot; &quot;&lt;!-- :&quot; &quot;: --&gt;&quot;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .wsf
::D&gt;
::D&gt;Hybridizing WSF the script looks for the XML declaration and makes it valid for running as batch. Also weird and undocumented trick with file extensions (`%~f0?.wsf`) is used to insist WSH to recognize the batch file as the WSF scenario. Honestly, the resulting file stops being well-formed XML file. However WSH chews it silently.
::D&gt;
::D&gt;BOM fails cmdizing.
::D&gt;
::D&gt;Assuming the original XML declaration is as follows:
::D&gt;
::D&gt;    &lt;?xml...?&gt;...
::D&gt;
::D&gt;further it becomes:
::D&gt;
::D&gt;    &lt;?xml :
::D&gt;    ...?&gt;&lt;!-- :
::D&gt;    prolog
::D&gt;    : --&gt;...
::D&gt;    the rest of WSF
::D&gt;
::D&gt;* http://www.dostips.com/forum/viewtopic.php?p=33963#p33963
::D&gt;
:cmdize.wsf	[/e cscript|wscript]
if not defined CMDIZE_ENGINE set &quot;CMDIZE_ENGINE=cscript&quot;

set &quot;CMDIZE_ERROR=&quot;

for /f &quot;tokens=1,* delims=:&quot; %%n in ( &#039;findstr /i /n /r &quot;&lt;?xml.*?&gt;&quot; &quot;%~f1&quot;&#039; ) do for /f &quot;tokens=1,2,* delims=?&quot; %%a in ( &quot;%%~o&quot; ) do for /f &quot;tokens=1,*&quot; %%d in ( &quot;%%b&quot; ) do (
	if %%n neq 1 set &quot;CMDIZE_ERROR=1&quot;
	if not &quot;%%a&quot; == &quot;&lt;&quot; set &quot;CMDIZE_ERROR=1&quot;
	if defined CMDIZE_ERROR (
		call :warn Incorrect XML declaration: it must be at the beginning of the script
		exit /b 1
	)

	rem We sure that the XML declaration is located on the first
	rem line of the script. Now we can transform it to the &quot;polyglot&quot;
	rem form acceptable by the batch file also.

	echo:%%a?%%d :
	call :print-prolog &quot;%CMDIZE_ENGINE% //nologo&quot; &quot;: %%e?&gt;&lt;!-- :&quot; &quot;: --%%c&quot; &quot;&quot; &quot;?.wsf&quot;

	for /f &quot;tokens=1,* delims=:&quot; %%a in ( &#039;findstr /n /r &quot;^&quot; &quot;%~f1&quot;&#039; ) do (
		if %%a gtr 1 echo:%%b
	)
	goto :EOF
)

call :print-prolog &quot;%CMDIZE_ENGINE% //nologo&quot; &quot;&lt;!-- :&quot; &quot;: --&gt;&quot; &quot;&quot; &quot;?.wsf&quot;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .kix
::D&gt;
:cmdize.kix
call :print-prolog kix32 &quot;&quot; &quot;&quot; &quot;;&quot;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .au3, .a3x
::D&gt;
:cmdize.au3
:cmdize.a3x
call :print-prolog AutoIt3 &quot;&quot; &quot;&quot; &quot;;&quot;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .ahk
::D&gt;
:cmdize.ahk
call :print-prolog AutoHotKey &quot;&quot; &quot;&quot; &quot;;&quot;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .php
::D&gt;
::D&gt;PHP is supposed to be used as a scripting language in Web. So to avoid possible conflicts with paths to dynamic libraries and to suppress HTTP headers, we use two options `-n` and `-q`, respectively.
::D&gt;
:cmdize.php
call :print-prolog &quot;php -n -q&quot; &quot;&lt;?php/* :&quot; &quot;*/ ?&gt;&quot;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::D&gt;## .jl
::D&gt;
::D&gt;* https://github.com/JuliaLang/julia/blob/master/doc/src/base/punctuation.md
::D&gt;* https://docs.julialang.org/en/v1/base/punctuation/
::D&gt;* https://forum.script-coding.com/viewtopic.php?pid=150262#p150262
::D&gt;
:cmdize.jl
call :print-prolog julia &quot;0&lt;#= :&quot; &quot;=#0;&quot;
type &quot;%~f1&quot;
goto :EOF

:: ========================================================================

::G&gt;# Hybridization internals
::G&gt;
::G&gt;This section discovers all guts of the hybridization.
::G&gt;

::G&gt;## `:print-usage`
::G&gt;
::G&gt;Prints different parts of the documentation.
::G&gt;
::G&gt;Arguments
::G&gt;
::G&gt;* `%1` - the marker
::G&gt;
::G&gt;The markers used specifically by this tool:
::G&gt;
::G&gt;* `U` - to print usage only
::G&gt;* `UH` - to print help (the `/HELP` option)
::G&gt;* `UHD` - to print help in details (the `/HELP-MORE` option)
::G&gt;* `UHDG` - to print full help including internals (the `/HELP-DEVEL` option)
::G&gt;
:print-usage
for /f &quot;tokens=1,* delims=&gt;&quot; %%a in ( &#039;findstr /r &quot;^::[%~1]&gt;&quot; &quot;%~f0&quot;&#039; ) do echo:%%b
goto :EOF

:: ========================================================================

::G&gt;## `:warn`
::G&gt;
::G&gt;A common use subroutine for displaying warnings to STDERR.
::G&gt;
::G&gt;Arguments
::G&gt;
::G&gt;* `%*` - a text for printing
::G&gt;
:warn
&gt;&amp;2 echo:%~n0: %*
goto :EOF

:: ========================================================================

::G&gt;## `:print-extension-list`
::G&gt;
::G&gt;Prints the list of supported extensions. It is invoked by the `/L` option.
::G&gt;
:print-extension-list
for /f &quot;tokens=1,* delims=.&quot; %%x in ( &#039;findstr /i /r &quot;^:cmdize[.][0-9a-z_][0-9a-z_]*\&gt;&quot; &quot;%~f0&quot;&#039; ) do echo:.%%~y
goto :EOF

:: ========================================================================

::G&gt;## `:print-script-wsf-bat`
::G&gt;
::G&gt;The purpose of this subroutine is to unify hybridizing a particular file as a WSF-file. It creates a temporary WSF-file with the content of the original file within and then hybridizes it.
::G&gt;
::G&gt;To this moment it is used only once - for VBScript.
::G&gt;
::G&gt;Arguments
::G&gt;
::G&gt;* `%1` - filename
::G&gt;* `%2` - language
::G&gt;
:print-script-wsf-bat
for %%f in ( &quot;%TEMP%\%~n1.wsf&quot; ) do (
	call :print-script-wsf &quot;%~f1&quot; %~2 &gt;&quot;%%~ff&quot;
	call :cmdize.wsf &quot;%%~ff&quot;
	del /f /q &quot;%%~ff&quot;
)
goto :EOF

::G&gt;## `:print-script-wsf`
::G&gt;
::G&gt;The companion for the above subroutine. It prints the original file surrounded with WSF markup.
::G&gt;
::G&gt;Arguments
::G&gt;
::G&gt;* `%1` - filename
::G&gt;* `%2` - language
::G&gt;
:print-script-wsf
echo:^&lt;?xml version=&quot;1.0&quot; ?^&gt;
echo:^&lt;package^&gt;^&lt;job id=&quot;cmdized&quot;^&gt;^&lt;script language=&quot;%~2&quot;^&gt;^&lt;^![CDATA[
type &quot;%~f1&quot;
echo:]]^&gt;^&lt;/script^&gt;^&lt;/job^&gt;^&lt;/package^&gt;
goto :EOF

:: ========================================================================

::G&gt;## `:print-prolog`
::G&gt;
::G&gt;This internal subroutine is a real workhorse. It creates prologs. Depending on the passed arguments it produces different prologs.
::G&gt;
::G&gt;Arguments
::G&gt;
::G&gt;* `%1` - engine (the executable invoking the script)
::G&gt;* `%2` - opening tag (used to hide batch commands wrapping them within tags)
::G&gt;* `%3` - closing tag (ditto)
::G&gt;* `%4` - prefix (used to hide batch commands in place)
::G&gt;* `%5` - pattern `f0` or `dpn0.extension` if `%4` == `@`; `?.wsf` for WSF-files only
::G&gt;
::G&gt;Common case (tagged)
::G&gt;
::G&gt;    call :print-prolog engine
::G&gt;    call :print-prolog engine tag1 tag2
::G&gt;
::G&gt;Both `tag1` and `tag2` are optional:
::G&gt;
::G&gt;    tag1
::G&gt;    @echo off
::G&gt;    engine %~f0 %*
::G&gt;    goto :EOF
::G&gt;    tag2
::G&gt;
::G&gt;Common case (prefixed)
::G&gt;
::G&gt;    call :print-prolog engine &quot;&quot; &quot;&quot; prefix
::G&gt;
::G&gt;The above invocation produces the prolog similar to the pseudo-code (the space after the prefix is here for readability reasons only):
::G&gt;
::G&gt;    prefix @echo off
::G&gt;    prefix engine %~f0 %*
::G&gt;    prefix goto :EOF
::G&gt;
::G&gt;Special case (`.wsf`)
::G&gt;
::G&gt;    call :print-prolog engine tag1 tag2 &quot;&quot; &quot;?.wsf&quot;
::G&gt;
::G&gt;It&#039;s almost the same as tagged common case:
::G&gt;
::G&gt;    tag1
::G&gt;    @echo off
::G&gt;    engine %~f0?.wsf %*
::G&gt;    goto :EOF
::G&gt;    tag2
::G&gt;
::G&gt;Special case (prefix = `@`)
::G&gt;
::G&gt;    call :print-prolog engine &quot;&quot; &quot;&quot; @ pattern
::G&gt;
::G&gt;It has higher priority and is processed prior others producing a code similar to:
::G&gt;
::G&gt;    @engine pattern %* &amp; @goto :EOF
::G&gt;
:print-prolog
if &quot;%~4&quot; == &quot;@&quot; (
	echo:@%~1 &quot;%%~%~5&quot; %%* ^&amp; @goto :EOF
	goto :EOF
)

setlocal

set &quot;tag=%~2&quot;
if defined tag (
	setlocal enabledelayedexpansion
	echo:!tag!
	setlocal
)

echo:%~4@echo off
echo:%~4%~1 &quot;%%~f0%~5&quot; %%*
echo:%~4goto :EOF

set &quot;tag=%~3&quot;
if defined tag (
	setlocal enabledelayedexpansion
	echo:!tag!
	setlocal
)

endlocal
goto :EOF

:: ========================================================================

::G&gt;## HOWTO
::G&gt;
::G&gt;This document is the part of the script and generated using the following command:
::G&gt;
::G&gt;    cmdize /help-devel | git-md-toc -cut &gt; doc/cmdize.md
::G&gt;
::G&gt;Any changes in the script are supposed to be replicated to this document file.
::G&gt;
::G&gt;`git-md-toc` is the Perl script hosted here:
::G&gt;
::G&gt;https://github.com/ildar-shaimordanov/git-markdown-toc
::G&gt;

:: ========================================================================

:: EOF
</code></pre></div></div></div>]]></summary>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2014-11-06T08:00:17Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=10114&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: Вывод разноцветного текста]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=8805&amp;action=new" />
			<summary type="html"><![CDATA[<p>Автор представленного решения (<a href="http://forum.script-coding.com/viewtopic.php?id=7944">обсуждение</a>) — <strong>Arigato</strong>.</p><p>Утилита FINDSTR при помощи ключа /A позволяет задать цвета текста и фона для выводимых имён файлов, в которых обнаружено соответсвие строке поиска (после имени файла теми же цветами выводится двоеточие, а затем, уже общими цветами окна консоли, строка, содержащая соответствие). Причём, если строка, содержащая соответствие, в файле последняя и не завершается переводом строки, то перевод строки после неё будет отсутствовать и в выводе FINDSTR.</p><p>Это используется в двух сдедующих процедурах, предназначенных для вывода текста заданного цвета:<br /></p><div class="codebox"><pre><code>:write
:: Вывести цветную надпись без перевода строки
:: %1 - цвет
:: %2 - текст надписи
:: %3 - флаг, любое значение, если нужно двоеточие в конце строки</code></pre></div><div class="codebox"><pre><code>:writeLn
:: Вывести цветную надпись с переводом строки
:: %1 - цвет
:: %2 - текст надписи
:: %3 - флаг, любое значение, если нужно двоеточие в конце строки</code></pre></div><p>Пример использования:<br /></p><div class="codebox"><pre><code>call :writeLn 2C &quot;   Hello, World   &quot;</code></pre></div><p>— выведет «Hello, World» красным цветом на зеленом фоне.</p><p>Особенности:<br />1. Цвет задается аналогично команде COLOR, т.е. цвет фона и текста двумя шестнадцатеричными цифрами.<br />2. Учитывая то, что цветным выводится имя файла, далеко не любой текст можно вывести этим методом. Текст должен быть допустимым с точки зрения составления имени файла.<br />3. В каталоге %TEMP% создается и затем удаляется временный подкаталог (если при создании подкаталога происходит ошибка, попытка повторяется для другого имени…).<br />4. В конце строки можно вывести двоеточие, хотя оно не может присутствовать в имени файла. Для этого надо установить любое значение в качестве третьего аргумента процедуры.<br />5. Пробелы в конце строки съедаются, в начале строки сохраняются.<br />6. В строках длинной 78 и 79 символов, т.е. если строка подходит к концу экрана, при выводе в конце могут добавиться двоеточие и точка (используемая здесь в качестве строки поиска FINDSTR). <em>(<span class="bbu">wisgest</span>: Точнее, в строках длиной n*w-1 и n*w-2, где n — целое число, w — ширина буфера экрана в символах, которая может отличаться от 80.)</em></p><p>Пример с двоеточием:<br /></p><div class="codebox"><pre><code>call :write 0F &quot;Random&quot; 1
call :writeLn 0E &quot; %random%&quot;</code></pre></div><p>В таком примере в конце строки будет выведено двоеточие зеленого цвета и точка обычного цвета <em>(<span class="bbu">wisgest</span>: если ширина буфера экрана составляет 80 символов)</em>:<br /></p><div class="codebox"><pre><code>call :writeLn 0A &quot;123456789012345678901234567890123456789012345678901234567890123456789012345678&quot;</code></pre></div><p>Сами процедуры с использующим их примером:<br /></p><div class="codebox"><pre><code>@ echo off
setlocal enabledelayedexpansion

call :write 0F &quot;Random&quot; 1
call :writeLn 0E &quot; %random%&quot;

echo:

set hex=0123456789ABCDEF
for /l %%j in (1, 1, 6) do (
  for /l %%i in (15, -1, 1) do (
    call :write !hex:~%%i,1!!hex:~%%j,1! &quot;[---]&quot;
  )
  echo:
)

echo:

call :writeLn 2C &quot;   Hello, World   &quot;

echo:

call :writeLn 0A &quot;123456789012345678901234567890123456789012345678901234567890123456789012345678&quot;

echo:

pause
color 0B
pause

endlocal
exit /b 0


:write
:: Вывести цветную надпись без перевода строки
:: %1 - цвет
:: %2 - текст надписи
:: %3 - флаг, любое значение, если нужно двоеточие в конце строки
  setlocal
  :write1
  set &quot;tempFolder=%TEMP%\%~n0.%time:~-2%.%random%&quot;
  md &quot;%tempFolder%&quot; 2&gt;nul || goto write1
  pushd %tempFolder%
  set /p .=.&lt;nul&gt;&quot;%~2&quot;
  findstr /a:%~1 /c:&quot;.&quot; /s &quot;%~2&quot;
  if &quot;%~3&quot;==&quot;&quot; (set /p .=  &lt;nul) else set /p .= &lt;nul
  popd
  rd /s /q &quot;%tempFolder%&quot; 2&gt;nul
endlocal &amp; exit /b

:writeLn
:: Вывести цветную надпись с переводом строки
:: %1 - цвет
:: %2 - текст надписи
:: %3 - флаг, любое значение, если нужно двоеточие в конце строки
  call :write %1 &quot;%~2&quot; %3
  echo:
exit /b
</code></pre></div><p>(т.к. имеются управляющие символы Backspace, используемые для удаления завершающего двоеточия с точкой, можете воспользоваться присоединённым файлом).</p>]]></summary>
			<author>
				<name><![CDATA[wisgest]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=3850</uri>
			</author>
			<updated>2013-10-23T19:01:00Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=8805&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: перевёртыш (зеркальное обращение текста)]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=7485&amp;action=new" />
			<summary type="html"><![CDATA[<p>При разработке и разгадке головоломок, запутанных и витееватых хитросплетений кода,&nbsp; да и просто &quot;JUST FOR LULZ&quot; :-D<br />, полезно иметь под рукой такую полезняшку.</p><br /><div class="codebox"><pre><code>@echo off
SETLOCAL EnableDelayedExpansion EnableExtensions
set tmpstr=
set text=%*
IF &quot;%~1&quot;==&quot;&quot; (set/p text= )
call :StrlenF &quot;%text%&quot; strlen
call :backstrF &quot;%text%&quot; %strlen% backstr
echo.
exit/b

:backstrF
    echo.

:proc_LOOP

set tmpstr=%tmpstr%!text:~%strlen%,1!


&lt;nul set /p  tmpstr=!text:~%strlen%,1!

set /a strlen-=1
if !strlen! EQU -1 (set %3=%tmpstr% &amp; exit /b)
goto :proc_LOOP
exit/b



:StrLenF ([in]str,[out]Length) 
:: -----------------------
:: Функция Нахождения длины строки /by Aскет/
:: -----------------------
    Set complen=0
    Set StringBuf=%~1
    If &quot;&quot;==&quot;%~1&quot; GoTo :EOF
    :StringLenLoop
    Set /A complen+=1
    Call Set StringChr=%%StringBuf:~%complen%%%
    set %2=%complen%
    If &quot;&quot;==&quot;%StringChr%&quot; GOTO :EOF
    GoTo :StringLenLoop
exit/b</code></pre></div><p>Вводить текст можно интерактивно, можно задавать его параметром запуска утилиты,<br />но также можно и обрабатывать файлы, пример:<br /></p><div class="quotebox"><blockquote><p><span style="color: gray">c:\&gt; TYPE C:\кадум\текст.txt|C:\кадум\перевертыш.bat</span></p><p><strong><span style="color: black">оговакул то сан ьвабзи он ,еинешукси в сан идевв ен и ;умешан укинжлод умокясв меащорп ым и оби ,ишан<br />ихерг ман итсорп и ;ьнед йыджак ан ман йавадоп йынщусан шан белх ;ебен ан как ,елмез ан и яовТ ялов те<br />дуб ад ;еовТ еивтсраЦ тедиирп ад ;еовТ ями яститявс ад !хасебен ан йищус ,шан ечто</span></strong></p></blockquote></div>]]></summary>
			<author>
				<name><![CDATA[Аскет]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25748</uri>
			</author>
			<updated>2012-08-21T22:19:11Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=7485&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: генерация пути для временного файла или папки]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=6259&amp;action=new" />
			<summary type="html"><![CDATA[<p>Функция генерирует и возвращает в переменной окружения «%TemporaryName%» путь для создания временного файла или папки:<br /></p><div class="codebox"><pre><code>@echo off
setlocal enableextensions enabledelayedexpansion

call :GetTemporaryName
echo Temporary name: [%TemporaryName%]

endlocal
exit /b 0

rem ==========================================================================
rem Функция GetTemporaryName()
rem 
rem Серый форум / CMD/BAT: генерация пути для временного файла или папки
rem (http://forum.script-coding.com/viewtopic.php?id=6259)
rem ==========================================================================
:GetTemporaryName
    setlocal enableextensions enabledelayedexpansion

:NextName
    set sTempName=%temp%\temp%random%.tmp

    if exist &quot;%sTempName%&quot; goto :NextName

    set sProcName=%~0

    endlocal &amp; set %sProcName:~4%=%sTempName%
    exit /b 0
rem ==========================================================================</code></pre></div><p>В функции использованы идеи из <a href="http://forum.script-coding.com/viewtopic.php?id=2944">CMD/BAT: возврат значений из процедур через параметры</a>.</p><p>Отдельное спасибо <strong>smaharbA</strong>.</p>]]></summary>
			<author>
				<name><![CDATA[alexii]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=1844</uri>
			</author>
			<updated>2011-09-28T01:31:27Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=6259&amp;action=new</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[CMD/BAT: получение ProductKey установленной Windows]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?id=5197&amp;action=new" />
			<summary type="html"><![CDATA[<div class="codebox"><pre><code>@echo off
setlocal enabledelayedexpansion

for /f &quot;tokens=3&quot; %%i in (&#039;reg.exe query &quot;HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion&quot; /v DigitalProductId&#039;) do (
    set x=%%~i
)

for /l %%z in (104, 2, 132) do (
    set /a array[%%z]=0x!x:~%%z,2!
)

call :GetKey
echo ProductKey: %GetKey%
rem pause &gt;nul

endlocal
exit /b 0

:GetKey
    setlocal enabledelayedexpansion
    set out=%~0
    set pc=BCDFGHJKMPQRTVWXY2346789
    set x=0
    for /l %%i in (0, 1, 28) do (
        if !x! gtr 28 goto :Break

        set a=0

        for /l %%j in (132, -2, 104) do (
            set /a a=array[%%j] + !a! * 256
            set /a array[%%j]=&quot;( !a! / 24 ) &amp; 255&quot;
            set /a a%%=24
            set /a n=%%j
        )

        for %%z in (!a!) do set key=!pc:~%%z,1!!key!
        set /a f=&quot;( !x! + 2 ) %% 6&quot;

        if !f! equ 0 if !x! lss 28 (
            set /a x+=1
            set key=-!key!
        )

        &lt;nul set /p sTemp=.
        set /a x+=1
    )
:Break
    echo.
    endlocal &amp; set %out:~1%=%key%
    exit /b</code></pre></div><p>Требуется наличие «reg.exe» в «PATH» (актуально для версий ниже Windows XP). См. также: <a href="http://forum.script-coding.com/viewtopic.php?id=522">VBScript: Получение ProductKey установленных Windows и MS Office</a>.</p><p>Автор идеи — <strong>smaharbA</strong>.</p>]]></summary>
			<author>
				<name><![CDATA[alexii]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=1844</uri>
			</author>
			<updated>2010-11-21T16:58:18Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?id=5197&amp;action=new</id>
		</entry>
</feed>
