« 2009年8月 | トップページ | 2009年10月 »

2009年9月22日 (火)

コマンドラインで、サスペンド(スリープ)、ハイバネーション(休止)する。(その7)

sleep.vbs

CreateObject("WScript.Shell").SendKeys "^{esc}{tab}{tab}{right}{right}s"

その他は、

W sWitch user
L Logoff
O lOck
R Reboot
S Sleep
H Hibanate
U shUtdown

2009年9月20日 (日)

コマンドラインで、サスペンド(スリープ)、ハイバネーション(休止)する。(その6)

suspend.vbs

CreateObject("Shell.Application").ShutdownWindows
Set wShell=CreateObject("WScript.Shell")
Do While Not wShell.AppActivate("Windows のシャットダウン")
  WScript.Sleep 100
Loop
wShell.SendKeys "%w{end}{up}{up}%k"

hibernate.vbs

CreateObject("Shell.Application").ShutdownWindows
Set wShell=CreateObject("WScript.Shell")
Do While Not wShell.AppActivate("Windows のシャットダウン")
  WScript.Sleep 100
Loop
wShell.SendKeys "%w{end}{up}%k"

日本語が送れるSendKeysならもっと確実に選択できるのですが、WScript.ShellのSendKeysは駄目なのです。英語圏は楽にできていいなぁ。
というか、ドロップダウンリストにはユニークなショートカットキーを付けてほしいものです。

2009年9月16日 (水)

WScript.Echo()で文字色や背景色などを変更する。(その2)

スクリプトからExcel経由でWin32APIを呼び出します。

Set Application=CreateObject("Excel.Application")
hwnd=Application.ExecuteExcel4Macro("CALL(""user32"",""FindWindowA"",""JCJ"",""ConsoleWindowClass"",0)")
pid=Application.ExecuteExcel4Macro("CALL(""user32"",""GetWindowThreadProcessId"",""2JN"","& hwnd &","& pid &")")
Call Application.ExecuteExcel4Macro("CALL(""kernel32"",""AttachConsole"",""JJ""," & pid & ")")
hConsole=Application.ExecuteExcel4Macro("CALL(""kernel32"",""CreateFileA"",""JCJJJJJJ"",""CONOUT$"",-1073741824,3,0,3,0,0)")

Echo 12,"赤"
Echo 9,"青"
Echo 14,"黄"
Echo &Hca,"赤"
Echo &H9a,"青"
Echo &Hea,"黄"
Echo 7,""

Call Application.ExecuteExcel4Macro("CALL(""kernel32"",""CloseHandle"",""JJ""," & hConsole & ")")

Sub Echo(wAttribute,Text)
Call Application.ExecuteExcel4Macro("CALL(""kernel32"",""SetConsoleTextAttribute"",""JJJ""," & hConsole & "," & wAttribute & ")")
WScript.StdOut.Write Text
End Sub

2009年9月15日 (火)

WScript.Echo()で文字色や背景色などを変更する。

xcolor.exeを使います。

文字列「赤青黄」をその文字色と緑の背景色で出します。

cscript cecho.vbs

cecho 10*16+12,"赤"
cecho &Ha9,"青"
cecho "&Hae","黄"
cecho 7,""

sub cecho(color,text)
createobject("wscript.shell").exec("xcolor.exe " & color).stdout.readall
wscript.stdout.write text
end sub

2009年9月14日 (月)

文字色や背景色などのコンソールテキスト属性を変更する。(その2)

VB.NETからWin32APIのSetConsoleTextAttribute()を呼び出します。

XColor.exe 属性

属性は、文字色(0~15)、背景色(&H00~&Hf0)、下線(&H8000)など。Color/?参照。
10進数または16進数(&H~)で。CMDでのエスケープは、"&H~" か ^&H~ で。

vbc XColor.VB

Public Class Class1

Private Const GENERIC_READ As Int32 = &H80000000
Private Const GENERIC_WRITE As Int32 = &H40000000
Private Const FILE_SHARE_READ As Int32 = &H00000001
Private Const FILE_SHARE_WRITE As Int32 = &H0000002
Private Const OPEN_EXISTING As Int32 = 3

Private Declare Auto Function CreateFile Lib "kernel32.dll" ( _
  ByVal lpFileName As String, ByVal dwDesiredAccess As Int32, _
  ByVal dwShareMode As Int32, ByVal lpSecurityAttributes As IntPtr, _
  ByVal dwCreationDisposition As Int32, ByVal dwFlagsAndAttributes As Int32, _
  ByVal hTemplateFile As IntPtr) As IntPtr
Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal hObject As IntPtr) As Boolean
Private Declare Function SetConsoleTextAttribute Lib "kernel32" (ByVal hConsoleOutput As Integer, ByVal wAttributes As Integer) As Integer

Public Shared Sub Main(ByVal Args() As String)
Dim wAttributes As Integer
If Args.Length=1 AndAlso IsNumeric(Args(0)) Then
  wAttributes = CInt(Args(0))
Else
  Console.WriteLine("Usage: XColor Attribute")
  Exit Sub
End If
Dim hConsoleOutput As Integer = CreateFile("CONOUT$", GENERIC_READ Or GENERIC_WRITE,  FILE_SHARE_READ Or FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, IntPtr.Zero, IntPtr.Zero)
SetConsoleTextAttribute(hConsoleOutput, wAttributes)
CloseHandle(hConsoleOutput)
End Sub
End Class

使用例、文字列「赤青黄」をその文字色で出します。

@echo off
xcolor 12
set <NUL /p x=赤
xcolor 9
set <NUL /p x=青
xcolor "&he"
set <NUL /p x=黄
xcolor 7

2009年9月13日 (日)

文字色や背景色などのコンソールテキスト属性を変更する。

Colorコマンドはコンソール全体の文字色や背景色を変えますが、部分的に変えることはできません。

そこで、部分的に文字色や背景色を変えるColorXコマンドを、OS(Vista)標準搭載のVB.NETで作ります。

ColorX.exe 文字色 [背景色]

文字色や背景色は、数字(0~15)か色の名前(Black~White)で指定します。

vbc ColorX.vb

Public Class Class1
Public Shared Sub Main(ByVal Args() As String)
If Args.Length = 0 OrElse Args.Length > 2 Then
  Console.WriteLine("Usage: ColorX ForegroundColor [BackgroundColor]")
  For Each ColorName As String In ConsoleColor.GetNames(GetType(ConsoleColor))
    Console.WriteLine("{0,2} {1}", [Enum].Format(GetType(ConsoleColor), CType([Enum].Parse(GetType(ConsoleColor), ColorName), ConsoleColor), "d"), ColorName)
  Next
  Exit Sub
End If
Try
  If Args.Length = 1 Then
    Console.ForegroundColor = CType([Enum].Parse(GetType(ConsoleColor), Args(0), True), ConsoleColor)
  Else
    Console.ForegroundColor = CType([Enum].Parse(GetType(ConsoleColor), Args(0), True), ConsoleColor)
    Console.BackgroundColor = CType([Enum].Parse(GetType(ConsoleColor), Args(1), True), ConsoleColor)
  End If
Catch
  Console.Error.WriteLine("Source" & vbTab & vbTab & Err.Source & vbLf & "Number" & vbTab & vbTab & Err.Number & vbLf & "Description" & vbTab & Err.Description & vbLf & "DLL Error" & vbTab & vbTab & Err.LastDLLError)
End Try
End Sub
End Class

使用例、文字列「赤青黄」をその文字色で出します。

@echo off
colorx red
set <NUL /p x=赤
colorx blue
set <NUL /p x=青
colorx yellow
set <NUL /p x=黄
colorx 7

2009年9月 9日 (水)

comm1バッチファイル

ファイル1にあって、ファイル2にない行を標準出力に出します。

comm1.cmd ファイル1 ファイル2

@echo off
findstr /X /L /V /G:%2 %1

unixのcommは入力がsortされている必要がありますが、こちらは必要ありません。
ただし、ファイル1は重複がないように、uniqされてる必要があります。もし、重複があると、重複します。

2009年9月 8日 (火)

comm3バッチファイル

ファイル1とファイル2に共通な行を標準出力に出します。

comm3.cmd ファイル1 ファイル2

@echo off
findstr /X /L /G:%2 %1

unixのcommは入力がsortされている必要がありますが、こちらは必要ありません。
ただし、ファイル1は重複がないように、uniqされてる必要があります。もし、重複があると、重複します。

2009年9月 7日 (月)

uniqバッチファイル

重複行を削除します。

uniq.cmd 入力ファイル 出力ファイル

@echo off
type nul >%2
for /f "delims=" %%I in (%1) do findstr /X /C:"%%I" %2 >NUL || (echo;%%I)>>%2

unixのuniqは、入力がsortされている必要がありますが、こちらはsortは必要ありません。

※読者氏の指摘で訂正。/L→/C

2009年9月 6日 (日)

タスクバーにCPU負荷を表示する。

バッチファイルで、

@echo off
for /L %%L in (0 0 1) do for /F "delims== tokens=2" %%I in ('wmic cpu get LoadPercentage /value') do title %%I%% & timeout 1 >NUL

ショートカットファイルで、

cmd.exe /q /c for /L %L in (0 0 1) do for /F "delims== tokens=2" %I in ('wmic cpu get LoadPercentage /value') do title %I% & timeout 1 >NUL

これらを最小化します。

Vistaでは、HomeBasicにも、wmicがあります。sleepは相変わらずありませんが、代わりに、timeoutやwaitforが使えます。

2009年9月 5日 (土)

wmicの出力は、リダイレクションとパイプで文字コードが異なる。

ファイルへのリダイレクションは、BOM付きUnicodeLEです。こちらの改行文字は正常です。CR+LF

一方、パイプは、シフトJISです。こちらの改行文字が変です。CR+CR+LF

ところで、for /F で読めるのは、シフトJISです。Unicodeは読めません。

なので、wmicの出力をファイルに出して、for /F %I in (ファイル) では読めません。
for /F %I in ('type ファイル') なら、シフトJISに変換されるので、読めます。改行文字の問題もありません。

また、for /F %I in ('コマンド') はパイプなので、wmicの出力がそのまま読めます。ただし、改行文字が。。。

2009年9月 4日 (金)

pingやwmicなど、改行文字がおかしい(CR+CR+LF)コマンド出力をforコマンドで処理する。

pingやwmicなどのコマンドの出力は改行文字がおかしい。CR+CR+LFになってます。
これをforコマンドで処理しようとすると、余分なCRがいろいろ悪さをします。

例えば、
wmic CPU GET LoadPercentage
の出力、
---
LoadPercentage 

2               

---
からCPU負荷を環境変数に取り出そうと、

for /F %%I in ('wmic CPU GET LoadPercentage') do set X=%%I
echo;%X%

のようにすると、取れないはずの空行が、余分なCRのために、余計に取れて邪魔をします。

面倒ですが、callを噛ましてCRを消し、ifで空行を除外します。

for /F %%I in ('wmic CPU GET LoadPercentage') do (call set J=%%I) & if defined J (call set X=%%I)
echo;%X%

あるいは、forをもう一段噛ます方法もあります。

for /F %%I in ('wmic cpu get LoadPercentage') do for /F %%J in ("%%I") do set X=%%J
echo;%X%

2009年9月 3日 (木)

pingやwmicなど、改行文字がおかしい(CR+CR+LF)コマンド出力を補正する。

pingやwmicなどのコマンドの出力は改行文字がおかしい。CR+CR+LFになってます。

見た目では分からないので、コマンドプロンプトで以下を試してみると、

for /f "delims=" %i in ('ping') do @echo;`%i'

行末の'が行頭の`を上書きして見えます。

あるいは、ファイルに書き出して、

(for /f "delims=" %i in ('ping') do @echo;`%i')>a.txt

メモ帳で見ると、行末の'の前でカーソル移動が1回停滞します。

さて、一度、ファイルに出力してから、改行文字を補正するには、以下を参照。

改行文字変換フィルタをバッチファイルで作る。(その2)
http://scripting.cocolog-nifty.com/blog/2008/11/post-8809.html

直接、コマンド出力を補正するには、callを噛まします。

for /f "delims=" %i in ('ping') do @call echo;%i

あるいは、コマンド出力を補正してファイルに書き出すには、

(for /f "delims=" %i in ('ping') do @call echo;%i)>a.txt

2009年9月 2日 (水)

FileSystemObjectの~.Pathがネットワークで文字化け?

FSOの旧版(~5.6)では、共有名に日本語などを使うと、~.Pathが文字化けします。
文字化けパターンからすると、共有名がUnicodeLEなのに、シフトJISだと思って、シフトJIS→Unicode変換しているようです。

そこで、~.Pathの代替関数を作って、~.Path の代わりに GetPathName(~) を使います。

ここで、~はFileまたはFolderオブジェクトです。

Dim fso
Set fso=CreateObject("Scripting.FileSystemObject")
MsgBox GetPathName(fso.GetFolder("\\サーバ名\共有名"))

Function GetPathName(fObject)
If fObject.Attributes And 16 Then
  If fObject.IsRootFolder Then
    GetPathName=fObject.Drive.Path & "\"
  Else
    GetPathName=fso.BuildPath(GetPathName(fObject.ParentFolder),fObject.Name)
  End If
Else
  GetPathName=fso.BuildPath(GetPathName(fObject.ParentFolder),fObject.Name)
End If
End Function

2009年9月 1日 (火)

バッチファイルでDEL文字を使う。

メモ帳では、CTRL+BS や ALT+(numキーの)127 で入力できますが、見た目では見えないので、環境変数に割り当てて使うとよいでしょう。

for /f %%I in ('cmd/u /cecho 使') do set DL=%%I
set DL=%DL:~0,1%
echo %DL%

« 2009年8月 | トップページ | 2009年10月 »