バッチファイルの文字コードをEBCDIC-Katakanaにしてみる。
これでバッチファイルのコードが素人目には隠蔽できるかも。
HOGE.CMD
---
chcp 20290
fdiw@≠ヤ%
---
« 2008年11月 | トップページ | 2009年1月 »
これでバッチファイルのコードが素人目には隠蔽できるかも。
HOGE.CMD
---
chcp 20290
fdiw@≠ヤ%
---
全角文字が使えないので、あまり使い道があると思えませんが、一応は可能です。
EBCDIC-Katakana.cmd Unicodeファイル EBCDIC-Katakanaファイル
start /min /wait cmd /c chcp.com 20290 ^& cmd /c type %1 ^>%2
xEBCDIC-Katakana.cmd EBCDIC-Katakanaファイル Unicodeファイル
start /min /wait cmd /c chcp.com 20290 ^& ^( set /p x=""^<nul ^& cmd /u /c type %1 ^) ^>%2
あまり実用的とは思えませんが、どうしても、EUC-JPでバッチファイルを書いて実行してみたい、という物好きな人は、
まず、以下のようなサンプルバッチファイルを作ります。
HOGE.CMD
---
echo 、「、、、ヲ、ィ、ェ
、「、、、ヲ、ィ、ェ.cmd
---
あいうえお.cmd
---
echo abc
---
最初に、コンソールのプロパティでフォントをMSゴシックに変えます。
必ず、その後で、コードページをEUC-JPに変えます。
chcp 20932
サンプルバッチファイルを実行します。
HOGE.CMD
必要なら、コードページをシフトJISに戻します。
chcp 932
シフトJIS(932) だけ? いいえ、そんなことはありません。例えば、EUC-JP(20932) も可能です。しかし、Unicode(1200)、UTF-7(65000)、UTF-8(65001)、JIS(50220) はダメです。
なので、実際上?は、シフトJIS(932) だけのようなものです。
これらコードページのバッチファイル可否は、%SystemRoot%System32\C_コードページ.NLS の有無によるようです。
もし、コンソールのコードページを UTF-7(65000)、UTF-8(65001)、JIS(50220)に変えると、バッチファイルが全く実行できなくなります。
また、これらのコードページでは、単にバッチファイルが実行できなくなるだけでなく、TYPE コマンドを除いて、ファイルの読み書きが全くできなくなるようです。
これはたぶん、ファイルの読み書きでは、C_コードページ.NLS を使用した文字コード変換が行なわれているせいなのでしょう。
逆に、UTF-7(65000)、UTF-8(65001)、JIS(50220) の C_コードページ.NLS を作ってやれば、それらのバッチファイルも可能になるかも知れません。
Unicode、UTF-8、UTF-7、JIS、EUC-JP、SJISなどの文字コードがcmd.exeとchcp.comだけで変換できます。
Unicode → 各種文字コード
UTF-7.cmd Unicodeファイル UTF-7ファイル
start /min /wait cmd /c chcp.com 65000 ^& cmd /c type %1 ^>%2
UTF-8.cmd Unicodeファイル UTF-8ファイル
start /min /wait cmd /c chcp.com 65001 ^& cmd /c type %1 ^>%2
JIS.cmd Unicodeファイル JISファイル
start /min /wait cmd /c chcp.com 50220 ^& cmd /c type %1 ^>%2
EUC-JP.cmd Unicodeファイル EUC-JPファイル
start /min /wait cmd /c chcp.com 20932 ^& cmd /c type %1 ^>%2
SJIS.cmd Unicodeファイル SJISファイル
start /min /wait cmd /c chcp.com 932 ^& cmd /c type %1 ^>%2
または、コードページが932なら、
type %1 >%2
各種文字コード → Unicode
以下のバッチファイルは、コードページ932専用です。
コードページ932以外で使用する場合は、以下を1行目に入れます。
for /f "delims=: tokens=2" %%i in ('chcp') do if not "%%i"==" 932" start /min /wait cmd /c chcp.com 932 ^& %0 %* & goto :eof
xUTF7.cmd UTF-7ファイル Unicodeファイル
start /min /wait cmd /c chcp.com 65000 ^& ^( set /p x=""^<nul ^& cmd /u /c type %1 ^) ^>%2
xUTF8.cmd UTF-8ファイル Unicodeファイル
start /min /wait cmd /c chcp.com 65001 ^& ^( set /p x=""^<nul ^& cmd /u /c type %1 ^) ^>%2
xJIS.cmd JISファイル Unicodeファイル
start /min /wait cmd /c chcp.com 50220 ^& ^( set /p x=""^<nul ^& cmd /u /c type %1 ^) ^>%2
xEUC-JP.cmd EUC-JPファイル Unicodeファイル
start /min /wait cmd /c chcp.com 20932 ^& ^( set /p x=""^<nul ^& cmd /u /c type %1 ^) ^>%2
xSJIS.cmd SJISファイル Unicodeファイル
( set /p x=""<nul & cmd /u /c type %1 ) >%2
ショートカットのホットキーは多重に起動できません。
しかし、インターネットショートカットのホットキーは多重に起動できます。
なので、多重に起動したいときは、ショートカットをインターネットショートカットに変えるとよいでしょう。
どうも、ショートカットのホットキーは、終了同期しているようです。
そこで、ショートカットのリンク先の先頭に、
rundll32 shell32,ShellExec_RunDLL 元のリンク先
を付けてもよいでしょう。
rundll32は元のリンク先を起動してすぐに終了するみたいなので。
CD2SFN.CMD
@ECHO OFF
FOR %%0 IN ("%CD%") DO FOR %%1 IN ("%%~dps0%%~nx0") DO CD %%~s1
CD2LFN.CMD
@ECHO OFF
SETLOCAL
CALL :GetLongFileName "%CD%"
(
ENDLOCAL
CD %LFN%
)
GOTO :EOF
:GetLongFileName
IF "%~p1"=="\" (SET LFN=%~d1) ELSE CALL :GetLongFileName "%~dp1."
FOR /F "delims=" %%1 IN ('ATTRIB "%LFN%\%~nx1"') DO SET LFN=%%1
SET LFN=%LFN:~11%
GetShortFileName.CMD 長いファイル/パス名
@ECHO OFF
IF NOT EXIST "%~1" (
ECHO ファイルが見つかりません - %1
GOTO :EOF
)
FOR %%1 IN ("%~dps1%~nx1") DO ECHO %%~s1
GetLongFileName.CMD 短いファイル/パス名
@ECHO OFF
SETLOCAL
IF NOT EXIST "%~1" (
ECHO ファイルが見つかりません - %1
GOTO :EOF
)
CALL :GetLongFileName %1
ECHO %LFN%
GOTO :EOF
:GetLongFileName
IF "%~p1"=="\" (SET LFN=%~d1) ELSE CALL :GetLongFileName "%~dp1."
FOR /F "delims=" %%1 IN ('ATTRIB "%LFN%\%~nx1"') DO SET LFN=%%1
SET LFN=%LFN:~11%
実用性は?ですが、原理が単純で、面白いので一度お試しあれ。:-)
[HKEY_CLASSES_ROOT\AllFilesystemObjects\Shell\パス名リストを作成\Command]
@="cmd /c echo \"%1\">>パス名リスト.txt"
フォルダでファイルなどを選択した後に、右クリックメニューから「パス名リストを作成」を実行します。
コンソールウィンドウが繰り返し開くのはご愛嬌です。:-p
そのフォルダにパス名リストを含む「パス名リスト.txt」が作成されます。
Windows Vistaには「パスとしてコピー」がありますが、Windows 2000やWindows XPにはありません。
そこで、以下のショートカットを作成して、「リンク」フォルダに入れます。
パスとしてコピー.lnk
mshta.exe "javascript:var i=new ActiveXObject('Shell.Application').Windows().Item().Document.SelectedItems();var a=new Array();for(var k=0;k<i.Count;k++){a[k]='"'+i.Item(k).Path+'"';}clipboardData.setData('text',a.join('\r\n'));close();"
フォルダでファイルなどを選択した後に、「リンク」から「パスとしてコピー」を実行します。
SendToフォルダにスクリプトなどを入れて「送る」場合は、引数の最大長の制限で、多数のファイルは送れません
しかし、ここでのやり方は、引数を使わないので、無制限に多数のファイルのパスをコピーできます。
※new ActiveXObject('Shell.Application').Windows().Item()の非互換でVista以降では使えません。
KB938129 - Windows Vista で 複数のファイルをアプリケーションのショートカットにドラッグ アンド ドロップすると起動に失敗することがある
http://support.microsoft.com/kb/938129/ja
これは、MS-DOS時代のコマンドラインの引数長127バイトの悪夢の再来だ。
Windows 2000/XPでは、コマンドライン長が2047/8191文字に拡張されて、あまり気にすることなく使えた。
XPでは、ショートカットに書けるコマンドライン長は260文字に制限されたが、ドロップで追加される引数はその別枠で、すべてを含めて8191文字に制限される。
しかし、Vistaでは、ショートカットのコマンドライン長が、ドロップで追加される引数も含めて、260文字に制限された。
これじゃ、ショートカットへのドロップは、まともに使えない。2、3個で駄目になる。最悪1個でも駄目になる。
Vistaでは、ドロップを使うときは、ショートカットをやめて、バッチファイルやスクリプトにでもするのだろうか?
ファイル名の中ににシフトJIS以外の文字があれば、_にリネームします。
yFileName.cmd ファイルセット...
@echo off
setlocal
for %%1 in (%*) do for /f "delims=" %%2 in ('echo %%1') do (
if not "%%~nx1"=="%%~nx2" (
echo %%1
echo %%2
set name="%%~nx2"
call rename "%%~1" %%name:?=_%%
)
)
Windows OSでのテキストファイルの改行文字は\r\nです。
一方、正規表現の改行文字は\nです。
なので、正規表現でテキストファイルを見ると、行末に\rがあります。
つまり、.*には、末尾に\rが付きます。
このようなトラブルを回避するには、先に\rを除去しておくとよいでしょう。
あるいは、.の代わりに[^\r\n]を使うとよいでしょう。
set re=new regexp
re.multiline=true
re.pattern=".+$"
set matches=re.execute("a" & vbcrlf & "b")
msgbox escape(matches(0).value),,"NG"
re.pattern="[^\r\n]+$"
set matches=re.execute("a" & vbcrlf & "b")
msgbox escape(matches(0).value),,"OK"
※
以前は、$は\nの直前にしかマッチせず、
| 行末hogeはhoge$に掛かりません。
| $の代わりに\r?$を使うとよいでしょう。
でしたが、\rの直前にもマッチするよう修正されたようです。
一般には、バッチファイルやスクリプトを作って、そのショートカットを作ることが行われていますが、ショートカットだけで十分です。
「リンク先」に、
cmd.exe /c start "" "アプリ1" & start "" "アプリ2"
「実行時の大きさ」は「最小化」にしておきます。
複数ファイルのパス名を改行区切りでクリップボードに送ります。
cmd.exe /c for /l %n in (1,1,2) do if %n==2 ((for %q in (%x%) do @echo %q)|MSHTA.EXE "javascript:clipboardData.setData('text',new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).ReadAll());close();") else set x=
複数ファイルのパス名を空白区切りでクリップボードに送ります。
cmd.exe /c for /l %n in (1,1,2) do if %n==2 (echo %x%|MSHTA.EXE "javascript:clipboardData.setData('text',new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).ReadAll());close();") else set x=
または、
cmd.exe /c for /l %n in (1,1,2) do if %n==2 (MSHTA.EXE "javascript:clipboardData.setData('text',new ActiveXObject('WScript.Shell').ExpandEnvironmentStrings('%x%'));close();") else set x=
テキストファイルの内容をクリップボードに送ります。
cmd.exe /c for /l %n in (1,1,2) do if %n==2 ((for %q in (%x%) do @type %q)|MSHTA.EXE "javascript:clipboardData.setData('text',new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).ReadAll());close();") else set x=