ネットワークの監査ツールを作成しているときに、通常のテキストをエコーするときに、WMICが各文字の間にスペースを入れて出力していることがわかりました。例えば、
この:
@echo off
echo Foo >> "C:\test.txt"
wmic CPU Get AddressWidth >> "C:\test.txt"
wmic CPU Get Description >> "C:\test.txt"
これを返します:
Foo
A d d r e s s W i d t h
6 4
D e s c r i p t i o n
I n t e l 6 4 F a m i l y 6 M o d e l 6 9 S t e p p i n g 1
(rem
)を削除すると、echo Foo
行、出力タイプが1つしかないため、出力は適切にフォーマットされます。
AddressWidth
64
Description
Intel64 Family 6 Model 69 Stepping 1
これは、WMICがUNICODEに出力するのに対し、標準のバッチコマンドはANSIに出力するためだと読んでいます。両方を結合して共通のフォーマットを共有できますか?誰かがさまざまな形式の種類、WMICがさまざまな種類に出力する理由、および/またはこの出力に寄与するその他の要因について詳しく説明できますか? パン粉 をいくつか見つけましたが、具体的なものはありません。
出力をWmic
からmore
にパイプします。wmic CPU Get AddressWidth |more >> "C:\test.txt"
背景を少し編集してください:表示される問題は、wmic
の出力がユニコードutf-16であるためです。これは、各文字(より正確には、ほとんどの文字)が2バイトでエンコードされることを意味します。 wmic
は、出力の先頭にいわゆるBOM(バイトオーダーマーク)も配置します。以下のバイトコンテンツを参照してください。
FF FE 44 00 65 00 73 00-63 00 72 00 69 00 70 00 ..D.e.s.c.r.i.p.
これらの最初の2バイト(FF FE)は、UTF-16のエンディアンを指定し、データ処理ツールがエンコーディングを認識できるようにします[UTF-16リトルエンディアン]。
明らかにtype
がこのチェックを行い、BOMが見つかった場合は、エンコーディングを正しく認識します。
一方、firstecho text
の後にWmic
出力を追加すると、最初にBOMがなく、エンコードに一貫性がないことがわかります。74 65 78 74 20 0D 0A 44-00 65 00 73 00 63 00 72 text ..D.e.s.c.r
type
を介してそれを解釈すると、解釈方法を推測できません。/ほとんどの場合、/は1バイト( 'ANSI')を想定し、これにより、印刷不可能な文字(ゼロ、実際には上位バイト)のためにスペースが生成されます。 2バイトの文字エンコード)。
more
は、より多くの(しゃれを意図した)ケースを処理し、基本的なASCII文字)の正しい出力を生成します。そのため、この目的のハックとして一般的に使用されます。
1つの追加の注意:一部のエディター(メモ帳が最も単純な例です)は、BOMがなくても、一貫性がある場合、utf-16でエンコードされたファイルを適切に表示します。 echo
に強制的にユニコード出力を生成させる方法があります(ただし、BOMを生成しないことに注意してください)-cmd /u
を使用すると、内部コマンドの出力がユニコードになります。
なぜcmdユニコードのサポートがそれほど制限されているのか(またはほとんどの人が言うように-壊れている...)-おそらく歴史的/互換性の問題を私は本当に言うことはできません。
最後に、(他の多くの利点の中でも)より優れたUnicodeサポートが必要な場合は、powershell
に移行することをお勧めします。
more
コマンドは変換をうまく行っていないようです。 x2.txt出力ファイルの二重CR(\ r)に注意してください。
C:>wmic diskdrive where "model = 'HGST HTS725050A7E630 ATA Device'" get index >x1.txt
C:>wmic diskdrive where "model = 'HGST HTS725050A7E630 ATA Device'" get index | more >x2.txt
C:>odd x1.txt
000000 ff fe 49 00 6e 00 64 00 65 00 78 00 20 00 20 00
377 376 I \0 n \0 d \0 e \0 x \0 \0 \0
000010 0d 00 0a 00 30 00 20 00 20 00 20 00 20 00 20 00
\r \0 \n \0 0 \0 \0 \0 \0 \0 \0
000020 20 00 0d 00 0a 00
\0 \r \0 \n \0
000026
C:>odd x2.txt
000000 49 6e 64 65 78 20 20 0d 0d 0a 30 20 20 20 20 20
I n d e x \r \r \n 0
000010 20 0d 0d 0a 0d 0d 0a 0d 0a
\r \r \n \r \r \n \r \n
pdate PowerShellがこれをより適切に処理できるようです。
Get-WmiObject Win32_diskdrive |
Where-Object { $_.Model -like '*WD*' } |
Select-Object -Property Model |
Out-File -PSPath t1.txt
Get-WmiObject Win32_diskdrive |
Where-Object { $_.Model -like '*WD*' } |
Select-Object -Property Model |
Out-File -PSPath t2.txt -Encoding default
CIMがPowerShellの将来の方向性であることは明らかです。今すぐ使い始めたほうがいいです。
Get-CimInstance CIM_DiskDrive |
Where-Object { $_.Model -like '*WD*' } |
Select-Object -Property Model |
Out-File -PSPath t1.txt
Get-CimInstance CIM_DiskDrive |
Where-Object { $_.Model -like '*WD*' } |
Select-Object -Property Model |
Out-File -PSPath t2.txt -Encoding default
WMICにデータをログファイルに追加させるだけでよい場合は、以下を試してください。
Test.bat
set Log=%~dpn0.log&::
set L=^>^>"%Log%" 2^>^&1 echo&::
%L% ^
wmic /APPEND:"%Log%" /locale:ms_409 service get name,startname,state,status&::
wmic /APPEND:"%Log%" /locale:ms_409 service get name,startname,state,status&::
notepad "%Log%"
exit
結果のTest.logファイルは次のようになります。
wmic /APPEND:"D:\Test\T.log" /locale:ms_409 service get name,startname,state,status
Name StartName State Status
AdobeARMservice LocalSystem Running OK
AJRouter NT AUTHORITY\LocalService Stopped OK
ALG NT AUTHORITY\LocalService Stopped OK
AppHostSvc LocalSystem Running OK
AppIDSvc NT Authority\LocalService Stopped OK