カテゴリ:プログラミング( 103 )
[VBScript] Delphi TIniFile風のINIファイル処理クラス
こんにチワワ。どーもボキです。

以前紹介したTIniFileクラスを、前回紹介したTListクラスを利用して、改良した。
(TIniFileクラスのソースは、記事の左下)

実行ソース
Set ini = New TIniFile

ini.Load(fpth) ' 読み込むINIファイルのフルパス

r = ini.ReadSections(slst)
' Functionのため、戻り値を受け取らないと正しく処理されない
' 戻り値を受け取らないのなら、ini.ReadSections slst と書く

For i = 0 To slst.Count -1
dprintf(slst(i))
r = ini.ReadSectionValues(slst(i), tlst)
For j = 0 To tlst.Count -1
dprintf(vbTAB & tlst(j))
Next
Next
a0021757_1517960.gif
IrfanViewのINIファイルを読み込ませたところ


TIniFileクラスのソース
[PR]
by yozda | 2012-06-23 15:25 | プログラミング | Trackback | Comments(0)
[VBScript] VBSへのドロップ実行ではホストやカレントディレクトリが異なる
おはヨーグルト。どーもボキです。

VBSファイルを実行するとき
「ダブルクリックで実行する場合」 と 「ドラッグ&ドロップで実行する場合」 とでは、
実行環境条件が多少異なる。

以下のソースファイルは「D:\DEV\VBS」に保存した。これを実行するとよく分かる。
Set objWS = CreateObject("WSCript.Shell")
MsgBox _
"ホスト" & vbTAB & ": " & WScript.FullName & vbCRLF &_
"カレント"& vbTAB & ": " & objWS.CurrentDirectory _
,64,"ホスト と カレントDir"
a0021757_76061.gif
ダブルクリックで実行した場合
ホストは設定値のまま、VBS保存フォルダで実行される

a0021757_76242.gif
ファイルドロップで実行した場合
ホストはWScriptとなり、ログインIDルートフォルダで実行される


ドロップ実行の場合、CScriptホストを指定しても、WScriptホストで実行される。
CScriptで実行したい場合は、引数を引き継いだ上で、指定したホストで実行するを利用するとよい。


[PR]
by yozda | 2012-06-23 07:09 | プログラミング | Trackback | Comments(0)
[VBScript] Delphi TStringList風のリストクラス
こんばんワイン。どーもボキです。

VBScriptは、文字列処理が得意だ。
Split や UBound を利用すれば、CSVファイルの処理も簡単に実現できる。

テキストファイルの処理をさらに簡単にするため、DelphiのTStringList風のクラスを作ってみた。
このクラスを使ったソースを実行すると、下画像のような実行結果となる。
a0021757_0191419.gif
Set List = New TList

' カンマ区切りで文字列を格納
List.Text(",") = "0,1,2,3,11,22,33"

' Index=1を""12.3""に更新"
List.Items(1) = "12.3"

' Index=0に4.56を挿入"
r = List.Insert(0, 4.56)

' List.Count, List(.Item)で格納値を取得
For i = 0 to List.Count-1
WScript.Echo vbTAB & "List("&i&") = "&List(i)
Next

' 文字列でソート"
List.Sort

' 数値でソート"
List.Numeric = True
List.Sort

' ファイル保存"
DPath = CreateObject("WScript.Shell").SpecialFolders("Desktop") &"\" ' デスクトップパス
s = Replace(Now,"
/","")
List.Save(DPath & Mid(s,3,InStr(s,"
")-3) & ".csv")


TListクラスのソース
[PR]
by yozda | 2012-06-20 00:21 | プログラミング | Trackback | Comments(0)
[VBScript] Craving Explorerの動画変換の終了後、PCをスタンバイにする
おはヨーグルト。ドーモボキです。

[VBScript] 指定プロセスのCPU使用率を監視し、アイドル状態になるまで待つ
 ↑
このときに考えてた、Craving Explorerの動画変換完了時にPCをスタンバイにするスクリプトを考えた。

指定した名前のプロセスが存在するか調べる
PCをスタンバイにする
引数を引き継いだ上で、指定したホストで実行する (処理メッセージを表示させるため)
 の組み合わせ。超、カンタン&シンプル。
SetScriptHost("CScript")    ' CScriptホストで実行 (変換メッセージを出すため)

Set objWS = CreateObject("WScript.Shell")

Count = 1
While 1
' 1sec間スリープ
WScript.Sleep 1000

' ffmpeg.exeの有無を調べる
If ProcessExists("ffmpeg.exe") Then
If Count <> 0 Then WSCript.StdOut.Write vbCRLF & "Wait" Else WScript.StdOut.Write "."
Count = 0
Else
If Count = 0 Then WSCript.StdOut.Write vbCRLF & "Check" Else WScript.StdOut.Write "."
Count = Count +1
End If

' 30sec間 ffmpes.exeが実行されていないなら変換終了 → スタンバイ
If Count = 30 Then
If objWS.PopUp("スタンバイにします",3,"変換終了",1+32) <> vbCancel Then
objWS.Run "rundll32 powrprof.dll,SetSuspendState"
End If
WScript.Quit
End If
WEnd

'-------------------------------------------------------------------------------
' プロセスが起動しているか調べる
Function ProcessExists(ProcessName)
Dim Service,QfeSet,Qfe,r

Set Service = WScript.CreateObject("WbemScripting.SWbemLocator").ConnectServer
Set QfeSet = Service.ExecQuery("Select * From Win32_Process Where Caption='" & ProcessName & "'")

r = 0
For Each Qfe In QfeSet
r = Qfe.ProcessId
Exit For
Next

ProcessExists = r <> 0
End Function

' -------------------------------------------------------------------------------
' 実行ホストを切り替える
Sub SetScriptHost(HostName)
If InStr(LCase(WSCript.FullName),LCase(HostName)) <> 0 Then Exit Sub

s = HostName & " """ & WScript.ScriptFullName & """"
If WScript.Arguments.Count > 0 Then
For i = 0 To WScript.Arguments.Count -1
s = s &" """ & WScript.Arguments.Item(i) & """"
Next
End If
CreateObject("WScript.Shell").Run s
WScript.Quit
End Sub


[PR]
by yozda | 2012-06-16 11:51 | プログラミング | Trackback(1) | Comments(0)
[VBScript] 引数を引き継いだ上で、指定したホストで実行する
おはヨーグルト。どーもボキです。

VBScriptの実行ホストは、デフォルトではWScript。
WScriptホストの場合、WScript.Echoすると、メッセージボックスが表示され処理が止まって不便だ。こんな感じに。
WScript.Shell の Popupを使えば、指定時間のみ表示するメッセージボックスを実現できるけどね。

なーんも知らんユーザにスクリプトホストをCScriptに変更させるのは難しいので、
スクリプト内で、引数を引き継いだ上で、ホストを指定して実行する方法を考えた。

ソース内の、「"""」は半角スペースを含んだパスをひとまとまりとして認識させるもの。
SetScriptHost("CScript")

WScript.StdOut.WriteLine "どーもボキです"
WScript.StdIn.ReadLine

' -------------------------------------------------------------------------------
' 実行ホストを切り替える
Sub SetScriptHost(HostName)
If InStr(LCase(WSCript.FullName),LCase(HostName)) <> 0 Then Exit Sub

s = HostName & " """ & WScript.ScriptFullName & """"
If WScript.Arguments.Count > 0 Then
For i = 0 To WScript.Arguments.Count -1
s = s &" """ & WScript.Arguments.Item(i) & """"
Next
End If
CreateObject("WScript.Shell").Run s
WScript.Quit
End Sub



[PR]
by yozda | 2012-06-16 10:59 | プログラミング | Trackback | Comments(0)
[VBScript] 指定した名前のプロセスが存在するか調べる
おはヨーグルト。ドーモボキです。

指定した名前のプロセスが実行されているかどうか調べるスクリプト。

どうでもいいことだが、CheckProcess と 動詞+名詞 としたかったが、
VBScriptには、FileExists、ForderExists があるので、それにあわせてみた。

MsgBox ProcessExists("Firefox.exe")

'-------------------------------------------------------------------------------
' プロセスが起動しているか調べる
Function ProcessExists(ProcessName)
Dim Service,QfeSet,Qfe,r

Set Service = WScript.CreateObject("WbemScripting.SWbemLocator").ConnectServer
Set QfeSet = Service.ExecQuery("Select * From Win32_Process Where Caption='" & ProcessName & "'")

r = 0
For Each Qfe In QfeSet
r = Qfe.ProcessId
Exit For
Next

ProcessExists = r <> 0
End Function

[VBScript] 指定した名前のプロセスを強制終了する

[PR]
by yozda | 2012-06-16 09:52 | プログラミング | Trackback | Comments(0)
[VBScript] PCをスタンバイにする
おはヨーグルト。どーもボキです。

VBScriptから、PCをスタンバイにする方法。他にもシャットダウン、再起動なども可能。
ただし、実行には管理者権限が必要。まぁフツー管理者で使うから問題ないだろ。
Set objWS = CreateObject("WScript.Shell")

' スタンバイ
objWS.Run "rundll32 powrprof.dll,SetSuspendState"

' 休止状態
objWS.Run "rundll32 powrprof.dll,SetSuspendState Hibernate"

' シャットダウン
objWS.Run "shutdown -s"

' 再起動
objWS.Run "shutdown -r"

' ログオフ
objWS.Run "shutdown -l"

上記のやり方では、休止状態が有効になっている場合、スタンバイにはならない。(SetSuspendState関数に引数を指定してないため)
ExcelがインストールされているPCならば、以下の方法でスタンバイに移行できる。
Set objExcel = CreateObject("Excel.Application")

' スタンバイ
cmd = "CALL(""powrprof.dll"",""SetSuspendState"",""JJJJ"",0,0,0)"

' 休止状態
cmd = "CALL(""powrprof.dll"",""SetSuspendState"",""JJJJ"",1,0,0)"

objExcel.ExecuteExcel4Macro(cmd)
objExcel.Quit ' QuitしないとExcelプロセスが残るため



管理者権限がない場合はこっち。こっちで使うSendKeysは、キーボード入力をスクリプトで再現するもの。
入力したキーは再前面のウィンドウが拾うので、PCを操作してたらうまく動かんかもしれん。
' タスクマネージャーを起動
Set objWS = CreateObject("WScript.Shell")
objWS.SendKeys "^+{esc}"
Do While Not objWS.AppActivate("Windows タスク マネージャ")
WScript.Sleep 100 ' タスクマネージャー起動待ち
Loop
WScript.Sleep 100

' ショートカットキーを送信
objWS.SendKeys "%ub%fx" ' スタンバイ
objWS.SendKeys "%uh%fx" ' 休止状態
objWS.SendKeys "%uu%fx" ' シャットダウン
objWS.SendKeys "%ur%fx" ' 再始動
objWS.SendKeys "%ul%fx" ' ログオフ



[PR]
by yozda | 2012-06-16 09:38 | プログラミング | Trackback | Comments(0)
[VBScript] 指定したタイトルキャプションのウィンドウを閉じる (※Word必須)
おはヨーグルト。どーもボキです。

[VBScript] 指定した名前のプロセスを強制終了する
 ↑
前回はプロセス名での操作、今回のはウィンドウキャプション。

キャプションに処理中の内容(ファイル名とか)が表示されるタイプのソフトであれば、
操作するウィンドウを細かに指定できる。

ただし、今回の方法が使えるのは、WordインストールされているPCのみ。


この方法ならば、ウィンドウを閉じるだけでなく、画面のサイズ・位置・最小/最大化を操作することができる。
また、APIのSendMessageも扱える。ただし、VBScriptはポインタを扱えないので自由度が少ない。
それでも、SendMessgeが使えるのはうれしいところ。

WordのTaskオブジェクトで扱えるプロパティ・メソッドの詳細は、コチラ
' 指定キャプションのウィンドウを閉じる
CloseWindow("( … > Z_ ̄∂")

'-------------------------------------------------------------------------------
Function CloseWindow(sCaption)
Dim objWord,Task,r

On Error Resume Next ' エラー処理OFF:Wordがない場合対応
r = False

Set objWord = CreateObject("Word.Application")
For Each Task in objWord.Tasks
If Task.Visible And (InStr(Task.Name, sCaption) <> 0) Then
Task.Close
r = True
Exit For
End If
Next
objWord.Quit ' Quit必須、これがないとWINWORD.exeがいつまでも残る

CloseWindow = r
On Error GoTo 0 ' エラー処理ON
End Function

[PR]
by yozda | 2012-06-16 08:49 | プログラミング | Trackback | Comments(0)
[VBScript] デバッグ上手はプログラム上手 ~追記~
こんばんワイン。どーもボキです。

デバッグメッセージを出力する前にTDebugクラスの生成が必要だったが、
dprintf実行時に自動生成するようにした。

こりゃ便利。
dprintf "   こ"
dprintf "   ん"
dprintf "   ば"
dprintf "   ん"
dprintf "   ワ"
dprintf "   イ"
dprintf "   ン"
dprintf "    ゜"
dprintf "   ど"
dprintf "   |"
dprintf "   も"
dprintf "   ボ"
dprintf "   キ"
dprintf "   で"
dprintf "   す"
dprintf "    ゜"

' -------------------------------------------------------------------------------
' デバッグ
Dim objDbg
' クラス
Class TDebug
Dim bCScript
' 初期化処理
Private Sub Class_Initialize()
bCScript = InStr(LCase(WSCript.FullName),"cscript") > 0
End Sub

' 終了処理
Private Sub Class_Terminate()
If Not bCScript Then Exit Sub

WScript.StdOut.WriteLine WScript.ScriptFullName & " [END]"
WScript.StdIn.ReadLine
End Sub

' デバッグメッセージ処理
Public Sub dprintf(v)
Dim i,s,ityp
If Not bCScript Then Exit Sub

s = v
ityp = VarType(v)
If ityp = vbBoolean Then
s = CStr(v)
ElseIf VarType(v) >= vbArray Then
s = ""
For i = 0 to UBound(v)
s = s & "dprintf(" &i& ")=" & v(i) & vbCRLF
Next
End If
WScript.Echo s
End Sub
End Class
' 関数
Sub dprintf(v)
If VarType(objDbg) = vbEmpty Then Set objDbg = New TDebug
objDbg.dprintf(v)
End Sub
a0021757_0291268.gif
実行イメージ


[VBScript] デバッグ上手はプログラム上手 ~サンプルプログラム1~6~

[PR]
by yozda | 2012-06-01 00:28 | プログラミング | Trackback | Comments(0)
[VBScript] 指定プロセスのCPU使用率を監視し、アイドル状態になるまで待つ
こんばんワイン。どーもボキです。

Craving Explorerは、かなり使える動画ダウンロード&変換ツールなんだけど、
時間の掛かる変換機能は、変換完了時のイベントを指定できない。

たとえば、変換に数時間かかる動画が終わったら、電源OFFるってのが出来ない。
なので、指定プロセスがアイドル状態(=CravingExplorer変換完了)かを判定するスクリプトを考えた。

以下は、指定したプロセスのCPU利用率を監視するサンプル。
サンプルではFirefoxがアイドル状態になるのをひたすら待ち受ける。
If WaitForProcessIdle("firefox.exe") Then MsgBox "アイドル状態" Else MsgBox "ない"

' -------------------------------------------------------------------------------
' True : 指定プロセスがアイドル状態になった(or 終了した)
' False : 指定プロセスが存在しない
Function WaitForProcessIdle(ProcessName)
'http://www.tek-tips.com/viewthread.cfm?qid=395765

WaitForProcessIdle = False
' プロセスIDを取得する
For Each Process in GetObject("winmgmts:").ExecQuery("Select * from Win32_Process where Name = '" & ProcessName & "'")
pID = Process.Handle
Exit For
Next
If pID = 0 Then Exit Function ' プロセスが見つからない
On Error Resume Next

WScript.StdOut.Write ProcessName &"(" & pID &")"

cmd = "Select * from Win32_PerfRawData_PerfProc_Process where IDProcess = '" & pID & "'"
Set objService = GetObject("Winmgmts:{impersonationlevel=impersonate}!\Root\Cimv2")
For Each objInstance in objService.ExecQuery(cmd)
n1 = objInstance.PercentProcessorTime
d1 = objInstance.TimeStamp_Sys100NS
Exit For
Next
Do
If objInstance.Name = "" Then Exit Do ' プロセスが終了
n0 = n1
d0 = d1
WScript.Sleep(1000)
WScript.StdOut.Write "."
For Each objInstance in objService.ExecQuery(cmd)
n1 = objInstance.PercentProcessorTime
d1 = objInstance.TimeStamp_Sys100NS
Exit For
Next
cpuusage = Round((n1 - n0)/(d1 - d0)*100, 0)
Loop Until cpuusage = 0 ' CPU使用率が0になるまでループ
WScript.StdOut.Write vbCRLF

On Error GoTo 0
WaitForProcessIdle = True
End Function
けど今回やりたかったことに対しては、このスクリプトは使えない。(このままでは)

それは、変換処理はCraving Explorerでなく、「ffmpeg.exe」が行っているからだ。
また、動画ごとにffmpeg.exeプロセスを立ち上げているようだ。(=動画ごとにffmpeg.exeのプロセスIDが変わる)

なので、スクリプトを作るとしたらこんな感じかな。
 1.一定時間ごとにffmpeg.exeプロセスが起動しているか確認する
 2.ffmpeg.exeプロセスが存在しない状態が10sec続くようなら、変換完了 → 電源OFF
このほうがずっとシンプルで確実。


[PR]
by yozda | 2012-05-30 00:23 | プログラミング | Trackback(2) | Comments(0)