« 2010年2月 | トップページ | 2010年4月 »

2010年3月31日 (水)

「お気に入りの整理」で使われているコントロール(NSC)を使う。

NSC(IShellFavoritesNameSpace)は、なぜかdialogでしか使えないようです。

そこで、バッチファイルかショートカットで、

mshta.exe vbscript:close(showmodaldialog("about:<object id=NSC classid=clsid:55136805-B2DE-11D1-B9F2-00A0C98BC547 width=500 height=500></object><script language=vbscript>sub window_onload:NSC.SetRoot ""shell:quick launch"":end sub:sub NSC_doubleclick:NSC.SelectedItem.InvokeVerb Empty:end sub</script>"))

フォルダを適宜変更。
ダブルクリックで関連付けのデフォルト動詞で起動します。

2010年3月30日 (火)

任意のフォルダを「お気に入りの整理」で開く。

フォルダの整理.HTA

<script language=vbscript>
'close(showModalDialog("res://ieframe.dll/ORGFAV.DLG ","shell:favorites"))

close(showModalDialog("res://ieframe.dll/ORGFAV.DLG ","shell:quick launch"))

'close(showModalDialog("res://ieframe.dll/ORGFAV.DLG ","c:\temp"))
</script>

2010年3月28日 (日)

Vistaで、IE.Navigate()する。IEオブジェクトを乗り継ぐ。(その4)

保護モード: 無効 -> 有効 の場合に対応するには、iexpore.exeを起こして乗り継ぎます。
複数タブ状態やタイミングエラーにも対応します。

Set wShell=CreateObject("WScript.Shell")
Path=wShell.RegRead("HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\iexplore.exe\")
Set Shell=CreateObject("Shell.Application")
Randomize
Do
  FullName=UCase(Mid(Path,1,1))
  For k=2 To Len(Path)
    If Fix(Rnd*2) Mod 2 Then
      FullName=FullName & UCase(Mid(Path,k,1))
    Else
      FullName=FullName & LCase(Mid(Path,k,1))
    End If
  Next
  For k = Shell.Windows().Count To 1 Step -1
    If Shell.Windows().Item(k - 1).FullName = FullName Then Exit For
  Next
Loop While k
wShell.Run """" & FullName & """ -nohome",0
Do
  For Each ie In Shell.Windows()
    If ie.Visible Then
    ElseIf ie.ReadyState Then
    ElseIf ie.FullName=FullName Then
      Exit Do
    End If
  Next
  WScript.Sleep 100
Loop
ie.Visible=True

Sub Navigate(URL)
hwnd=ie.HWND
LocationURL=ie.LocationURL
Set dic=CreateObject("Scripting.Dictionary")
For Each ix In Shell.Windows()
  If hwnd=ix.HWND Then dic.Add ix,Empty
Next
ie.Navigate URL
Do
  Call TryWaitForReady(ie,hwnd,dic)
Loop While Err.Number
End Sub

Sub TryWaitForReady(ie,hwnd,dic)
On Error Resume Next
Call WaitForReady(ie,hwnd,dic)
End Sub

Sub WaitForReady(ie,hwnd,dic)
Do
  For Each ix In Shell.Windows()
    If hwnd=ix.HWND And Not dic.Exists(ix) Then
      Set ie=ix
      Exit For
    End If
  Next
  If Not ie.Busy And ie.ReadyState=4 Then Exit Do
  WScript.Sleep 100
Loop
End Sub

Navigate URL1
MsgBox ie.LocationURL
Navigate URL2
MsgBox ie.LocationURL

2010年3月27日 (土)

Vistaで、IE.Navigate()する。IEオブジェクトを乗り継ぐ。(その3)

IEオブジェクトが遷移するとき、一時的にShellWindowsに同居するようなので、早目にhwndをキーに乗り移ります。
旧オブジェクトが消えてから乗り移るより、タイミングエラーが少なくて済みます。

Set Shell=CreateObject("Shell.Application")
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
hwnd=ie.HWND
ie.Navigate URL
Do
  For Each ix In Shell.Windows()
    If hwnd=ix.HWND And Not ix Is ie Then
      Set ie=ix
      Exit For
    End If
  Next
  If Not ie.Busy And ie.ReadyState=4 Then Exit Do
  WScript.Sleep 100
Loop
MsgBox ie.LocationURL

2010年3月24日 (水)

ファイルの場所を開く。

Vistaでショートカットや「検索結果」のファイルなどを右クリックすると、「ファイルの場所を開く」というメニュー項目があります。XPでは、「1 つ上のフォルダを開く」でした。

「送る」メニューに「ファイルの場所を開く」を作るには、sendtoフォルダにショートカット「ファイルの場所を開く.lnk」、リンク先:
explorer.exe /select,
を作ります。

フォルダナビゲーションペインがあったほうがよければ、
explorer.exe /e,/select,

任意のファイル、フォルダの右クリックに「ファイルの場所を開く」を作るには、以下のレジストリを結合します。

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\AllFilesystemObjects\Shell]
@="open"

[HKEY_CLASSES_ROOT\AllFilesystemObjects\Shell\OpenFileLocation]
@="ファイルの場所を開く(&1)"

[HKEY_CLASSES_ROOT\AllFilesystemObjects\Shell\OpenFileLocation\Command]
@="explorer.exe /select,\"%1\""

2010年3月21日 (日)

ショートカットキーを無効にする。

F1キーやF3キーを押し間違えて、鬱陶しいときは、NOPに変えてしまいます。
F1キーを無効にするには、デスクトップなどにリンク先、
WScript.exe //B
のショートカットを作り、プロパティでショートカットキーにF1を設定します。

2010年3月20日 (土)

「Window フォト ギャラリー」「Windows フォト ビューアー」のショートカットを作る。

XPの「Windows 画像と Fax ビューア」は、Vistaで「Window フォト ギャラリー」に代わり、Windows7では「Windows フォト ビューアー」に名前が変わりました。

シンタクスがフルパス引用符なし、なので、バッチファイルでは、

start rundll32.exe "%ProgramFiles%\Windows Photo Gallery\PhotoViewer.dll", ImageView_Fullscreen %~f1

ですが、普通には、ショートカットに書けません。

そこで、ショートカットでは、一捻りして、

cmd.exe /v:on /c for /l %n in (1,1,2) do if %n==2 (for %q in (!x!) do start %SystemRoot%\System32\rundll32.exe "%ProgramFiles%\Windows Photo Gallery\PhotoViewer.dll", ImageView_Fullscreen %~fq) else set x=

2010年3月19日 (金)

Run Applications at a Low Integrity Level (その2)

アプリを「整合性レベル:低」で起動するにはどうするか?

「保護モード:有効」のIEは、「整合性レベル:低」なので、これを利用します。

「整合性レベル:低」のフォルダ「お気に入り」や「お気に入りバー」に、

low.htm

<a href=lowcmd.cmd>lowcmd.cmd</a><br>
<a href=lowexplorer.cmd>lowexplorer.cmd</a><br>

lowcmd.cmd

@echo off
for /f "tokens=3 delims=\ " %%i in ('whoami /groups^|find "Mandatory"') do set LEVEL=%%i
echo %LEVEL%
cmd

lowexplorer.cmd

@echo off
for /f "tokens=3 delims=\ " %%i in ('whoami /groups^|find "Mandatory"') do set LEVEL=%%i
echo %LEVEL%
explorer.exe /separate,shell:cache

を作成します。

low.htmを開いて、そこからlowcmd.cmdやlowexplorer.cmdを起こすと、「整合性レベル:低」で動きます。

あるいは、「保護モード:有効」のページを開き、メニューバーの「お気に入り(A)」からlowcmd.cmdやlowexplorer.cmdを起こすと、「整合性レベル:低」で動きます。

2010年3月18日 (木)

引数を「ファイル名を指定して実行」に「送る」。

FileRunX.exe [引数...]

用途
(a) SendToフォルダに置いて、ファイルを「送る」。
(b) ショートカットなどのコマンドラインに前置して、実行前に確認ダイアログを出す。
(c) ショートカットなどのコマンドラインに前置して、実行時に引数の追加変更ダイアログを出す。

vbc /t:winexe FileRunX.vb

Imports System.Text
Imports System.Threading

Delegate Function CallBack(hwnd As Integer, lParam As Integer) As Boolean

Module Module1

Declare Auto Function SHRunDialog Lib "shell32" Alias "#61" (hWnd As Integer, hIcon As Integer, lpszPath As String, szTitle As String, szPrompt As String, uFlags As Integer) As Integer
Declare Function EnumWindows Lib "user32" (lpEnumFunc As CallBack, IParam As Integer) As Integer
Declare Function GetWindowThreadProcessId Lib "user32" (hwnd As Integer, ByRef ProcessId As Integer) As Integer
Declare Auto Function GetClassName Lib "user32" (hwnd As Integer, lpClassName As StringBuilder, nMaxCount As Integer) As Integer
Declare Auto Function FindWindowEx Lib "user32" (hWndParent As Integer, hWndChildAfter As Integer, lpszClassName As String, lpszWindowCaption As Integer) As Integer
Declare Auto Function SendMessage Lib "user32" (hwnd As Integer, wMsg As Integer, wParm As Integer, lParm As String) As Integer
Const WM_SETTEXT As Integer=&H000C
Dim hwnd As Integer

Sub Main()
Dim FileRunThread As New Thread(AddressOf FileRun)
FileRunThread.IsBackground=True
FileRunThread.Start()
Dim sTitle As String = "ファイル名を指定して実行" & Chr(0)
Dim sPrompt As String = "実行するプログラム名、または開くフォルダやドキュメント名、インターネット リソース名を入力してください。" & Chr(0)
SHRunDialog(0, 0, Environment.CurrentDirectory, sTitle, sPrompt, 0)
End Sub

Sub FileRun()
Dim CommandLine As String = System.Environment.CommandLine
Dim Quoted As Boolean = False
Dim k As Integer
For k=0 To CommandLine.Length-1
  If CommandLine.Chars(k) = """" Then
    Quoted = Not Quoted
  ElseIf Not Quoted AndAlso CommandLine.Chars(k) = " " Then
    Exit For
  End If
Next
CommandLine = CommandLine.Remove(0,k).Trim()
'  Console.WriteLine("Arguments:{0}",CommandLine)

If CommandLine.Length=0 Then Exit Sub
System.Threading.Thread.Sleep(0)
Do
  hwnd=0
  EnumWindows(AddressOf EnumFunc, System.Diagnostics.Process.GetCurrentProcess().Id)
  If hwnd Then
    hwnd = FindWindowEx(hwnd, 0, "ComboBox", 0)
    If hwnd Then
      SendMessage(hwnd, WM_SETTEXT, 0, CommandLine)
      Exit Sub
    End If
  End If
  System.Threading.Thread.Sleep(100)
Loop
End Sub

Function EnumFunc(hwnd1 As Integer, lParam As Integer) As Boolean
Dim pid As Integer
GetWindowThreadProcessId(hwnd1, pid)
Dim sb1 As New StringBuilder(256)
GetClassName(hwnd1, sb1, sb1.Capacity + 1)
If lParam=pid And sb1.ToString()="#32770" Then
  hwnd=hwnd1
  Return False
End If
Return True
End Function

End Module

2010年3月17日 (水)

ショートカットに相対パスを指定する。(その3)

こういう手もあります。

%windir%\System32\mshta.exe vbscript:close(createobject("wscript.shell").run("相対パス [引数...]",1))

"相対パス [引数...]"の中で引用符を使うときは2重にします。
"""相対 パス"" [""引 数""...]"

ショートカットの「実行時の大きさ」の代わりに、,1))の数字で指定します。
0 非表示
1 通常のウィンドウ
3 最大化
7 最小化

2010年3月16日 (火)

複数の「ファイル名を指定して実行」を開く。

Vistaでは、なぜか「ファイル名を指定して実行」がひとつしか開きません。
そこで、.NETで作ります。

vbc /t:winexe FileRun.vb

Module Module1
Declare Auto Function SHRunDialog Lib "shell32" Alias "#61" (hWnd As Integer, hIcon As Integer, lpszPath As String, szTitle As String, szPrompt As String, uFlags As Integer) As Integer
Sub Main()
Dim sTitle As String = "ファイル名を指定して実行"
Dim sPrompt As String = "実行するプログラム名、または開くフォルダやドキュメント名、インターネット リソース名を入力してください。"
SHRunDialog(0, 0, Environment.CurrentDirectory, sTitle, sPrompt, 0)
End Sub
End Module

2010年3月14日 (日)

「フォルダショートカット」を作り分ける。

Vistaでは、フォルダをドラッグ&ドロップするとき、
ALTキーを押し下げると、フォルダへのショートカットファイル(.lnk)、
CTRL+SHIFTを押し下げると、「フォルダショートカット」フォルダができます。

※「フォルダショートカット」は循環参照にならないよう注意が必要です。

※Windows7では駄目。

2010年3月12日 (金)

ショートカットに相対パスを指定する。(その2)

Vistaでは、ShellExec_RunDLLの仕様が変わったようで、この用途に使えません。:-(
また、フォルダも開けなくなりました。なぜだろう?セキュリティ強化?

%windir%\system32\rundll32.exe shell32.dll,ShellExec_RunDLL "絶対パスまたはファイル名" [引数...]

ファイル名やベース名はPATHを検索します。
相対パスやフォルダ名はNOPになります。

では、相対パスで指定するには、

%windir%\explorer.exe "相対パス"

または、

%windir%\system32\rundll32.exe url.dll,FileProtocolHandler "相対パス"

この場合、引数は指定できません。

引数を指定する場合は、

%windir%\system32\cmd.exe /c start "%cd%" "相対パス" [引数...]

ショートカットのプロパティで、
いずれの場合も、作業フォルダを空にします。
cmd.exeの場合、実行時の大きさを最小化にします。

2010年3月11日 (木)

スクリプトでスリープを抑止する。(その2)

もちろん、SetThreadExecutionState()関数を使う方法もあります。

SetThreadExecutionState.vbs

Set Excel=CreateObject("Excel.Application")
'Const ES_SYSTEM_REQUIRED=1
'Const ES_DISPLAY_REQUIRED=2
'Const ES_CONTINUOUS=-2147483648
MsgBox Hex(Excel.ExecuteExcel4Macro("CALL(""kernel32"",""SetThreadExecutionState"",""JJ"",-2147483647)")),,"Sleep抑止中(システム)"
'MsgBox Hex(Excel.ExecuteExcel4Macro("CALL(""kernel32"",""SetThreadExecutionState"",""JJ"",-2147483646)")),,"Sleep抑止中(モニター)"
'MsgBox Hex(Excel.ExecuteExcel4Macro("CALL(""kernel32"",""SetThreadExecutionState"",""JJ"",-2147483648)")),,"Sleep抑止解除"

2010年3月10日 (水)

スクリプトでスリープを抑止する。

Vistaでは、なんでも、WM_POWERBROADCASTのPBT_APMQUERYSUSPENDが来ないらしく、BROADCAST_QUERY_DENYが返せないとか。
代わりに、SetThreadExecutionState()を出しておけとか。

SetThreadExecutionState()関数の解説記事によれば、
「ローカルのキーボードまたはマウスによる入力、サーバーアクティビティ、ウィンドウフォーカス切り替えなどのアクティビティは、システムで自動的に検出されます。」

ならば、スクリプト的には、

SleepDenier.vbs

set wshell=createobject("wscript.shell")
do while wshell.popup("Sleep 抑止中 ...",60,"Sleep Denier",)=-1
  wshell.sendkeys "%{tab}"
loop

2010年3月 9日 (火)

ウィンドウからプロセスを特定する。

このウィンドウは誰が出してるのか?
同じアプリが複数動いているとき、ウィンドウで特定するには?

タスクマネジャのアプリケーションタブでタスクを右クリック「プロセスの表示」→プロセスタブで選択されたもの。

同じタイトルで区別できないときは、右クリック「手前に表示」などで、特定する。

2010年3月 8日 (月)

スクリプトから「ウィンドウを切り換える」。

Vista の IShellDispatch5 で可能になりました。

CreateObject("Shell.Application").WindowSwitcher()

2010年3月 7日 (日)

スクリプトからフォルダのソートキーを変える。

Vista の IShellFolderViewDual3 で可能になりました。

例えば、名前の昇順は、
ie.Document.SortColumns = "prop:System.ItemNameDisplay;"

更新日時の降順は、
ie.Document.SortColumns = "prop:-System.DateModified;"

解除は、ないので、値のない総ファイル サイズ
ie.Document.SortColumns = "prop:System.TotalFileSize;"
や、値が同じフォルダ名
ie.Document.SortColumns = "prop:System.ItemFolderNameDisplay;"
で代替します。

解除されてるときに、ie.Document.SortColumnsを見るとゴミ。(障害)

2010年3月 4日 (木)

Vistaのエクスプローラには「リンクバー」がない。「上へ」ボタンもない。

Vistaのエクスプローラには「上へ」のボタンもありません。
メニューだと「表示」「移動」「1つ上の階層へ」の3手が必要です。
「リンクバー」があればスクリプトを入れて2手にできますが、それもありません。
ではどうするか?
フォルダペインの背景メニューに「1つ上の階層へ移動」を追加します。

GoUp.vbsを作ります。

CreateObject("WScript.Shell").SendKeys "%{up}"

レジストリを編集します。

[HKEY_CLASSES_ROOT\directory\background\shell\GoUp]
@="1つ上の階層へ移動"

[HKEY_CLASSES_ROOT\directory\background\shell\GoUp\command]
@="wscript.exe \"C:\\どこかのフォルダ\\GoUp.vbs\""

背景メニューか、ファイルメニューから選べます。

2010年3月 3日 (水)

IE7/IE8で、アクティブなIEを捕捉する。

IEの「お気に入りセンタ」か「お気に入りバー」から起動すれば、そのウィンドウのアクティブタブのIEを捕捉します。

GetCurrentIE.vbs

Set ies=CreateObject("Shell.Application").Windows()
For Each ie In ies
  If ie.ReadyState=4 Then If TypeName(ie.Document)="HTMLDocument" Then If ie.Document.hasFocus() Then Exit For
Next
If IsEmpty(ie) Then
  For Each ie In ies
    If ie.ReadyState<>4 Then
    ElseIf TypeName(ie.Document)="HTMLDocument" Then
      ie.Document.focus
      If ie.Document.hasFocus() Then Exit For
    End If
  Next
End If
If IsEmpty(ie) Then
  MsgBox "Not Found"
Else
  MsgBox ie.LocationURL,,ie.Document.title
End If

※ スクリプトファイル(またはそのショートカット)は他で作って、「お気に入り」か「お気に入りバー」に「移動」で入れること。

※ ウィンドウのフォアグラウンドロックを利用しているので、フォアグラウンドロックを無効(タイムアウト値を0)にしていると使えません。

2010年3月 2日 (火)

IEのFORMへの入力がESCキーで消えるのを防止する。

かな漢字変換をESCキーで戻すとき、間違って余分に叩くとFORMの入力がすべて消えちゃいます。:-<

自分のページなら、FORMのonkeydownでキャンセルします。

<FORM onkeydown="javascript:if(event.keyCode==27) return false;">
<INPUT type="text">
</FORM>

他人のページの場合、HTAからIEを監視して、documentのonkeydownを書き換えます。

IE Form Eacape Canceler.hta

<head><title>IE Form Eacape Canceler</title>
<script language=vbscript>
resizeTo 285,10
setInterval "proc",1000

Sub proc
For Each ie In CreateObject("Shell.Application").Windows()
  If InStr(LCase(ie.FullName),"iexplore.exe") Then
    Set ie.Document.onkeydown=GetRef("onkeydown")
  End If
Next
End Sub

Sub onkeydown
If Me.parentWindow.event.keyCode=27 Then Me.parentWindow.event.returnValue=False
End Sub
</script>
</head>

2010年3月 1日 (月)

エクスプローラのフォルダの「並べ替え」を解除する。

「並べ替え」が効いていると自動で並べ替えられて鬱陶しいことがあります。
「並べ替え」を解除することができないのでしょうか?

「表示」の「並べ替え」には「昇順」と「降順」の二者択一しかありません。
なので、値がないか、すべて同じ値を持つカラムを一度表示して、それをソートキーにして、そのカラムを非表示に戻します。

例えば、総ファイル サイズ。本当はフォルダのサイズが出るはずだけど出ないので。
あるいは、フォルダ名。すべて同じ値なので。

カラムが値がないか、すべて同じ値を持つかどうかは「昇順」「降順」を切り換えて順番が変わるかどうかで分かります。

※Vistaまでは、行をドラッグ&ドロップで移動しても解除できるようです。Windows7では不可。

« 2010年2月 | トップページ | 2010年4月 »