タグ:VBScript ( 55 ) タグの人気記事
[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] 指定プロセスの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)
[VBScript] 指定した名前のプロセスを強制終了する
こんにチワワ。どーもボキです。

うちの環境(XP home SP3 + IE7)だけかもしれんが、IEが正常に終了しないことが多い。(プロセスが残る)
Youtubeのような動画サイトを閲覧中に終了させるとこの現象が起きるっぽい。

タスクマネージャーで一つ一つ終了させるのは面倒なので、スクリプトを作った。
ここでいうプロセス名とは、タスクマネージャーのプロセス一覧で表示される名前のこと。
' IEを強制終了する
TerminateProcess("iexplore.exe")

'-------------------------------------------------------------------------------
' 指定した名前のプロセスを強制終了
Sub TerminateProcess(ProcessName)
Dim objProcList,objProcess

Set objProcList = GetObject("winmgmts:").InstancesOf("win32_process")
For Each objProcess In objProcList
If LCase(objProcess.Name) = LCase(ProcessName) Then objProcess.Terminate
Next
End Sub



[PR]
by yozda | 2012-05-27 12:29 | プログラミング | Trackback(3) | Comments(0)
[VBScript] ドラッグ&ドロップ処理ツールのテンプレート
こんにチワワ。どーもボキです。

VBSファイル(または、ショートカット)にドロップされたファイルを処理するスクリプト。
フォルダがドロップされた場合は、サブフォルダも含め、そのなかのすべてのファイルを処理する。

とりあえずCSVファイルが対象。
' 引数なし
If WScript.Arguments.Count = 0 Then WScript.Quit

Set objWS = CreateObject("WScript.Shell")
Set objFS = CreateObject("Scripting.FileSystemObject")

' 引数でループ
For i = 0 To WScript.Arguments.Count -1: Do
s = WScript.Arguments.Item(i)

If objFS.FileExists(s) Then
ProcFile(s)
Else
SearchFile(s)
End If
Loop Until 1: Next

r = objWS.PopUp("処理が終了しました。",3,"終了メッセージ",64)
'============================================================


' フォルダ内のファイル---------------------------------------
Sub SearchFile(DPath)
Set Folder = objFS.GetFolder(DPath)

' フォルダ内のフォルダ
For Each SubFolder In Folder.SubFolders: Do
SearchFile(SubFolder.Path)
Loop Until 1: Next

' フォルダ内のファイル
For Each File In Folder.Files: Do
ProcFile(File.Path)
Loop Until 1: Next
End Sub

' ファイル処理メイン ----------------------------------------
Function ProcFile(FPath)
ProcFile = False
If LCase(Right(FPath,3)) <> "csv" Then Exit Function
' ※※※処理実体を記述※※※

ProcFile = True
End Function
' ----------------------------------------------------------



[PR]
by yozda | 2012-04-30 13:53 | プログラミング | Trackback | Comments(7)
[VBScript] 右クリックメニュー > 送る で選択したファイルをバックアップする
こんばんワイン。どーもボキです。

プログラムやドキュメントを作成&編集する際、直前のバージョンを残したい時が多々ある。

Ctrl+ファイルのドラッグで、「コピー~ファイル名」のようにコピーファイルを残すのも手だ。
けど、ファイル名の「コピー~」が不細工。
マメにリネームする人ならとくもかく、ボキのようなズボラは、すぐに何のためのコピーなのかわからんなる。

なんで、VBScirpt と 右クリックメニュー > 送る を組み合わせて、
ファイルバックアップツールを作った。
導入方法
 1.以下のソースを、メモ帳にコピーする
 2.適当な名前をつけメモ帳を保存し、拡張子を「vbs」にする
 3.2のファイル自身(またはショートカット)を、
   C:\Documents and Settings\Administrator\SendTo に保存する
 以上。
'※バックアップ先フォルダを固定したい場合は、
' 以下のコメントを外し、適宜パスを編集すること
'cDPath_BackUp = "D:\BackUp\"

If WScript.Arguments.Count = 0 Then WScript.Quit

Set objWS = CreateObject("Wscript.Shell")
Set objFS = CreateObject("Scripting.FileSystemObject")

s = Now
b = Mid(s,13,1) = ":" ' 時間が一桁か判定、True/False=-1/0

ymd_hms = Mid(s,3,2) & Mid(s,6,2) & Mid(s,9,2) &"_" ' 月日が一桁の場合は、「0がつく」
h = Mid(s,12,2+b): If b Then h = "0" & h ' 時間が一桁の場合は、「0がつかない」
ymd_hms = ymd_hms & h & Mid(s,15+b,2) & Mid(s,18+b,2)

' backupフォルダを作成
dpth = cDPath_BackUp
' 指定フォルダがない場合は、ドロップされたパスにフォルダ作成
If dpth = "" Then dpth = objFS.GetParentFolderName(WScript.Arguments.Item(0)) &"\backup\"
If Not objFS.FolderExists(dpth) Then objFS.CreateFolder(dpth)

' 日付フォルダを作成
dpth = dpth & ymd_hms
cmnt = InputBox("
コメントつける?")
If cmnt <> "
" Then dpth = dpth &"_"& cmnt
dpth = dpth &"
\"
If Not objFS.FolderExists(dpth) Then objFS.CreateFolder(dpth)

' 選択ファイル・フォルダをコピー
For Each pth In WScript.Arguments :Do
If objFS.FolderExists(pth) Then
r = objFS.CopyFolder(pth, dpth)
Else
r = objFS.CopyFile(pth, dpth)
End If
Loop Until 1 :Next
利用イメージ
a0021757_2314076.gif
バックアップしたいファイルを選択し(複数もOK)、右クリックメニュー > 送る > バックアップvbs

a0021757_2313378.gif
必要なコメント入力 (フォルダ名となるので、禁止文字は入れられない。「\」とかね。)
a0021757_2313618.gif
年月日時分秒_任意コメントのフォルダが作成され、その中にコピーがとられる


[PR]
by yozda | 2011-09-19 23:06 | プログラミング | Trackback | Comments(0)
符号なし32ビット整数で4294967295(2^32-1)から、さらに+1するとどーなる?
こんばんワイン。どーもボキです。

符号なし32bit整数、Cならunsigned long、DelphiならCardinal。
この符号なし整数は、0 ~ (2^32)-1、つまり0 ~ 4294967295 まで格納できる。

4294967295 のとき、さらに+1するとどーなるか?


答え、0 になる。
4294967295(10)= FFFFFFFF(Hex)
 ↓
 ↓+1
 ↓
4294967296(10)=100000000(Hex)
したから8桁(4バイト=32ビット)使われるので、0になる。

なら、4294967295 よりも大きい値をカウントしたいときはどうしたらいいと思う?
↓↓

答え
[PR]
by yozda | 2011-06-30 00:08 | SE♂日誌 | Trackback | Comments(0)
[VBScript] ラジオボタンダイアログを実現する その2
こんにチワワ。どーもボキです。

より改良したものはこちら

こん時のソース。IEをQuitしてなかったので、実行のたびにiexplore.exeが残ってしまってた。なので修正。

あとアイテムリストが指定数以上の場合は、プルダウンメニュー表示させる機能を追加した。
a0021757_1519732.gif
ラジオボックスで表示 (もともとの機能)


a0021757_151954.gif
上図は表示指定数=1とした場合。指定数=10とすると、画面上に10個は表示される。([∨]を押すと全項目が表示される)


それにしてもIEを使って実現しているから、実行は遅いよね。
すなおにInputBox使ったほうがストレスはないかもね。

以下、ソース。前回同様onclickのo(全角)は、o(半角)にして。
[PR]
by yozda | 2011-03-09 15:21 | プログラミング | Trackback(1) | Comments(0)
[VBScript] 実行フォルダ内のYYYYMMDD…形式のファイルをYYYYMMフォルダに移動する
どーもボキです。

VBS実行フォルダにある、YYYYMMDD…形式のファイル名がつけられたファイルを、
YYYYMMってフォルダを作って移動するスクリプト。

N82の写真が、同じフォルダにすべて転送されてしまったから、スクリプトでフォルダ分け処理させた。
自分用の簡単なスクリプト(毎回、簡単だけど)なので、2000年からしか処理できない。
(If Left(file.Name,2) <> "20" Then の行ね。)

FileSystemObjectを利用すれば、YYYYMMDD…形式のファイルに限らず、
ファイルの更新日でフォルダを分けたり、
デジカメの時間設定ミスで更新日時がズレてしまったファイルの一括で修正したりもできる。
Set objFS = WScript.CreateObject("Scripting.FileSystemObject")

DPath_VBS = objFS.GetParentFolderName(WScript.ScriptFullName) & "\"

Set folder = objFS.GetFolder(DPath_VBS)

For Each file In folder.Files :Do
If Left(file.Name,2) <> "20" Then Exit Do ' 次のファイルへ

dname = Left(file.Name,6) ' フォルダ名:YYYYMM

DPath_To = DPath_VBS & dname & "\"

' YYYYMMフォルダがなければ作成
If Not objFS.FolderExists(DPath_To) Then objFS.CreateFolder(DPath_To)

' ファイル移動
objFS.MoveFile DPath_VBS & file.Name, DPath_To
Loop Until 1 :Next
a0021757_0243931.gif
動作イメージ



[PR]
by yozda | 2011-02-08 00:33 | プログラミング | Trackback | Comments(0)
[VBScript] デバッグ上手はプログラム上手 ~サンプルプログラム1~6~
どーもボキです。

サンプルプログラム
1~6で扱った内容を入れています。

[PR]
by yozda | 2010-12-03 22:32 | プログラミング | Trackback(1) | Comments(0)