2022年5月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
無料ブログはココログ

« 2007年1月 | トップページ | 2007年3月 »

2007年2月28日 (水)

スクリプトからWin32APIをCALLして、ウィンドウを最前面に表示する。

もし、Excelがあれば、スクリプトからWin32APIをCALLすることができます。

以下は、ウィンドウタイトル「電卓」を最前面に表示します。

'Const HWND_TOPMOST = -1
'Const SWP_NOSIZE = 1
'Const SWP_NOMOVE = 2

Set Application=CreateObject("Excel.Application")
hwnd=Application.ExecuteExcel4Macro("CALL(""user32"",""FindWindowA"",""JJC"",0,""電卓"")")
RC=Application.ExecuteExcel4Macro("CALL(""user32"",""SetWindowPos"",""JJJJJJJJ""," & hwnd & ",-1,0,0,0,0,3)")
If RC=0 Then MsgBox "ウィンドウが見つかりません。"

2007年2月27日 (火)

バッチファイルで、CSVファイルをHTMLファイルの<table>に変換する。

csv2html.cmd csvファイル >htmlファイル

@ECHO OFF
ECHO ^<html^>
ECHO ^<body^>
ECHO ^<table border^>
FOR /F "delims=" %%1 IN (%1) DO (
ECHO ^<tr^>
FOR %%2 IN (%%1) DO (
ECHO ^<td^>
ECHO %%~2
ECHO ^</td^>
)
ECHO ^</tr^>
)
ECHO ^</table^>
ECHO ^</body^>
ECHO ^</html^>

ただし、CSVファイルは、空白、タブ、=;,で区切られ、
空白、タブ、=;,を含む項目は、""で囲まれていなければなりません。

2007年2月26日 (月)

コマンドラインからアプリやバッチを非表示で実行する。

スタートアップやショートカット、ATコマンド、タスクスケジューラ、関連付けなどの
コマンドラインからアプリやバッチを最小化や非表示で実行するには?

非表示実行.CMD コマンドライン

@ECHO OFF
SETLOCAL
SET X=%*
START /MIN MSHTA.EXE vbscript:close(CreateObject("WScript.Shell").Run("%X:"=""%",0))

コマンドラインに直接書くなら、

MSHTA.EXE vbscript:close(CreateObject("WScript.Shell").Run("""c:\hoge\hoge.exe"" ""引 数"" ...",0)+resizeTo(0,0))

ショートカットなら、ショートカットを最小化にして、

MSHTA.EXE vbscript:close(CreateObject("WScript.Shell").Run("""c:\hoge\hoge.exe"" ""引 数"" ...",0))

関連付けなら、

MSHTA.EXE vbscript:close(CreateObject("WScript.Shell").Run("""%1""",0)+resizeTo(0,0))

非表示でなく、最小化なら、Run(,0)をRun(,7)に。

2007年2月25日 (日)

IEとExplorerの区別(~IE6.0)

Shell.Windows()はwindow?(HTMLWindow?)のコレクションではなく、
IEまたはExplorer(IWebBrowser2)のコレクションです。

必然的に、IEとExplorerを区別したくなりますが、それは間違いです。

IEでもフォルダを開くことができるし、ExplorerでもWebページを開くことができるからです。
(IE6.0まで。IE7.0以降は不可。)

正しくは、フォルダかWebページかを区別します。

Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows()
  If InStr(TypeName(ie.Document),"IShellFolderView") Then
    MsgBox "Explorer" & vbTab & ie.LocationURL
  Else
    MsgBox "IE" & vbTab & ie.LocationURL
  End If
Next

または、

Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows()
  If TypeName(ie.Document)="HTMLDocument" Then
    MsgBox "IE" & vbTab & ie.LocationURL
  Else
    MsgBox "Explorer" & vbTab & ie.LocationURL
  End If
Next

フォルダの場合、バージョンにより名前が異なるので、部分一致で判定します。

2007年2月24日 (土)

コマンドラインでExcelファイルのマクロを呼び出す。

MSHTA.EXE vbscript:Execute("Set xl=CreateObject(""Excel.Application""):xl.Visible=True:Set bk=xl.WorkBooks.Open(""%cd%\hoge.xls""):xl.Run(""sheet1.func"",""引数""):bk.Close:Set bk=Nothing:xl.Quit():Set xl=Nothing:close:")

Excelファイルをコマンドラインで印刷する。

ExcelPrint.CMD ファイル

MSHTA.EXE vbscript:Execute("Set xl=CreateObject(""Excel.Application""):xl.AutomationSecurity=2:Set bk=xl.WorkBooks.Open(""%~f1""):bk.PrintOut:bk.Close:Set bk=Nothing:xl.Quit:Set xl=Nothing:resizeTo 0,0:close:")

ExcelPrint.VBS ファイル

Set xl=CreateObject("Excel.Application")
xl.AutomationSecurity=2
Set bk=xl.WorkBooks.Open(WScript.Arguments.Item(0))
bk.PrintOut
bk.Close
Set bk=Nothing
xl.Quit
Set xl=Nothing

ExcelPrintTo.CMD ファイル "プリンタ名"

MSHTA.EXE vbscript:Execute("Set xl=CreateObject(""Excel.Application""):xl.AutomationSecurity=2:Set bk=xl.WorkBooks.Open(""%~f1""):Call bk.PrintOut(,,,,""%~2""):bk.Close:Set bk=Nothing:xl.Quit:Set xl=Nothing:resizeTo 0,0:close:")

ExcelPrintTo.VBS ファイル "プリンタ名"

Set xl=CreateObject("Excel.Application")
xl.AutomationSecurity=2
Set bk=xl.WorkBooks.Open(WScript.Arguments.Item(0))
Call bk.PrintOut(,,,,WScript.Arguments.Item(1))
bk.Close
Set bk=Nothing
xl.Quit
Set xl=Nothing

Excelファイルの関連付けで、DDEを使わないようにする。

Excelファイルの関連付けは、DDEを使用していますが、これはトラブルの元です。

「開く」は、DDEを使わないようにできますが、「印刷」はどうするか?

「開く」
"~\EXCEL.EXE" "%1"

WorkBooks.Open(ファイル)に相当します。

「新規」
"~\EXCEL.EXE" /n "%1"

WorkBooks.Add(ファイル)に相当します。

元の関連付けにあった /e オプションは、起動時にブック指定がないとき、デフォルトの Book1 などを開かないことを指示します。

「印刷」
MSHTA.EXE vbscript:Execute("Set xl=CreateObject(""Excel.Application""):xl.AutomationSecurity=2:Set bk=xl.WorkBooks.Open(""%1""):bk.PrintOut:bk.Close:Set bk=Nothing:xl.Quit:Set xl=Nothing:resizeTo 0,0:close:")

または、

WScript.exe "~\ExcelPrint.VBS" "%1"

「PrintTo」
MSHTA.EXE vbscript:Execute("Set xl=CreateObject(""Excel.Application""):xl.AutomationSecurity=2:Set bk=xl.WorkBooks.Open(""%1""):Call bk.PrintOut(,,,,""%2""):bk.Close:Set bk=Nothing:xl.Quit:Set xl=Nothing:resizeTo 0,0:close:")

または、

WScript.exe "~\ExcelPrintTo.VBS" "%1" "%2"

元の動詞は「~2」に変えて、メニュー名を「DDEで~」に変えて、
文字列値extendedを付けておけば、シフトキー+右クリックメニューで使えます。

2007年2月23日 (金)

Excelの設定変更の振る舞いについて

例えば、Application.IgnoreRemoteRequestsをTrue/Falseに変更したとき、
Excelがいつ、どのような条件でレジストリに反映するのか?

それは、

アプリ終了時に、
アプリが持つ最終的な値が、
アプリ始動時にレジストリから読み込んだ値と異なると、
レジストリに書き込む。

ということのようです。

2007年2月22日 (木)

HTAでもwindow.close()は復帰します!

WScript.Quit()は復帰しません。ヘルプにもそう書いてあります。

| WScript.Quit (1);
|
| // このコード行は実行されません。
| var i = 0;

しかし、HTAでのwindow.close()を同様に考えていると嵌ります。

以下のコードをhoge.htaにして実行してみてください。

<script>
close();
open();
</script>

HTAは終了しますが、open()が実行されてIEが開きます。

同様に、以下を実行してみてください。

<script language=vbscript>
set wshell=createobject("wscript.shell")
close
wshell.popup 1
</script>

何度か繰り返すと、たまにpopupが表示されることがあります。

なので、
If エラーケース Then
  window.close
End If
通常処理
End Sub/Functionなど
のようなコードは駄目です。

If エラーケース Then
  window.close
  Exit Sub/Functionなど
End If
通常処理
End Sub/Functionなど

If エラーケース Then
  window.close
Else
  通常処理
End If
End Sub/Functionなど
のようにしないといけません。

2007年2月21日 (水)

Windows2000+WSH5.6で使える「ファイルを開く」ダイアログ

WindowsXPなら、いろいろ使えるのですが、Windows2000だと、困ります。
HtmlDlgHelperにopenfiledlg()がありますが、HTMLに組み込まないと使えないみたい。
そこで、これをHTAに動的に組み込んで使います。

MsgBox OpenFileDlg("C:\Program Files\*.txt","テキスト (*.txt)|*.txt|すべてのファイル (*.*)|*.*|","ファイルの選択")

Function OpenFileDlg(Path,Filter,Title)
Dim oExec
Set oExec=CreateObject("WScript.Shell").Exec("MSHTA.EXE ""javascript:new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).ReadAll()""")
oExec.StdIn.WriteLine "<object id=HtmlDlgHelper classid=CLSID:3050f4e1-98b5-11cf-bb82-00aa00bdce0b></object>"
oExec.StdIn.WriteLine "<script language=vbscript>"
oExec.StdIn.WriteLine "resizeTo 0,0"
oExec.StdIn.WriteLine "Sub window_onload()"
oExec.StdIn.WriteLine "CreateObject(""Scripting.FileSystemObject"").GetStandardStream(1).Write HtmlDlgHelper.object.openfiledlg(""" & Path & """,,""" & Filter & """,""" & Title & """)"
oExec.StdIn.WriteLine "close"
oExec.StdIn.WriteLine "End Sub"
oExec.StdIn.WriteLine "</script>"
oExec.StdIn.WriteLine "<hta:application caption=no showintaskbar=no />"
oExec.StdIn.Close
OpenFileDlg=oExec.StdOut.ReadAll()
If InStr(OpenFileDlg,vbNullChar) Then OpenFileDlg=Left(OpenFileDlg,InStr(OpenFileDlg,vbNullChar)-1) '注意!
End Function

注意!
openfiledlg()は、Null Terminated String、所謂'SZ'で返ってくる変な仕様なので、切り捨てます。

2007年2月20日 (火)

VBAで、テキストファイルの文字コードを自動判定します。

Function CharSetOfText(Path)
Dim fso
Dim File
Dim htmlfile
Set fso = CreateObject("Scripting.FileSystemObject")
Set File = fso.GetFile(Path)
File.Name = File.Name & ".txt"
Set htmlfile = GetObject(File.Path, "htmlfile")
Do While htmlfile.readyState <> "complete"
  Application.Wait Now + TimeSerial(0, 0, 1)
Loop
CharSetOfText = htmlfile.CharSet
File.Name = fso.GetBaseName(File.Name)
End Function

2007年2月19日 (月)

ExcelオートメーションでDDE要求を無視する。の別解は駄目

一般的には、Application.IgnoreRemoteRequestsを操作しますが、これは、Excelのオプション設定「他のアプリケーションを無視する」を変更します。

そこで、オプション設定を変えない、全く別の方法、
「DDE処理用のExcelを別に先に起こす。」
を考えたのですが、駄目です。

どのExcel.ApplicationがDDE要求に応答するか、不定なようです。

2007年2月18日 (日)

ExcelオートメーションでDDE要求を無視する。

Excelオートメーションで処理しているときに、Excelファイルを関連付けで開いたり、印刷すると、Excelオートメーションの処理中にDDE要求が入って来て、困ります。

なので、Excelオートメーションの処理中は「他のアプリケーションを無視する」とよいでしょう。
ただし、「他のアプリケーションを無視する」のは、そのオートメーション処理中のExcelだけで、他のExcelの設定を変えないようにするには若干コツが必要です。

Set Application=CreateObject("Excel.Application")

の代わりに、

Set Application=GetApplication()

とします。

以下のVBSファイルは、そういうExcelを起こして、ブックを開きます。

IgnoreRemoteRequests.VBS [ブック...]

Option Explicit

Dim Application
Dim Arg

Set Application=GetApplication()
Application.Visible=True
Application.UserControl=True
For Each Arg In WScript.Arguments
  Application.WorkBooks.Open Arg
Next

Function GetApplication()
Dim Application
Dim IgnoreRemoteRequests

Set Application=CreateObject("Excel.Application")
IgnoreRemoteRequests=Application.IgnoreRemoteRequests
If IgnoreRemoteRequests=False Then Application.IgnoreRemoteRequests=True
Application.Quit
Set Application=Nothing
Set GetApplication=CreateObject("Excel.Application")
If IgnoreRemoteRequests=True Then Exit Function
Set Application=CreateObject("Excel.Application")
Application.IgnoreRemoteRequests=False
Application.Quit
Set Application=Nothing
End Function

2007年2月17日 (土)

環境変数のPATHを行分けして表示するバッチファイル(続編)

遅延展開を使って;を改行文字(LF)に置換すると簡単です。

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET LF=^(改行)
(改行)
(改行)
ECHO %PATH:;=!LF!%

これは、; でばらすだけです。

以下は、; でばらして、さらに、" " で囲みます。

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET LF=^(改行)
(改行)
(改行)
SET PATH=%PATH:;=!LF!%
FOR /F "usebackq delims=" %%1 IN ('!PATH!') DO ECHO;"%%~1"

ここで、FOR /F IN ("文字列")の中で改行文字(LF)を使うと、「複数行の文字列」になります。

2007年2月16日 (金)

.NETアプリで、自分がコンソールアプリか、Windowsアプリか調べる。

自分が/target:exeか、/target:winexeか、どちらでコンパイルされているか、
を調べるにはどうするか?

Try
  System.Diagnostics.Process.GetCurrentProcess().WaitForInputIdle(0)
  MsgBox("Windowsアプリです。")
Catch
  Console.WriteLine("コンソールアプリです。")
End Try

.NETのWindowsアプリでもリダイレクトすれば標準入出力が使えます。

前編はこちら。
VB6アプリやEXCEL VBAなどのWindowsアプリから標準入出力を使用する方法
その続編です。

.NETのConsole.Write()やJScript.NETのprint()は、通常、コンソールアプリで使用しますが、
Windowsアプリ(/target:winexe)でもリダイレクトすれば使えます。

もし、Windowsアプリ(/target:winexe)でリダイレクトされてなければ、NOPです。

その判定方法は、書いてみて、もし、Err.LastDLLError=0なら、OK、
Err.LastDLLError=6なら、NOP、と判定できそうです。

2007年2月15日 (木)

IFコマンドを遅延展開する。

ECHOやSETは、CALLと%%で遅延展開できましたが、IF文は出来ませんでした。

(参照) 「CALLコマンドと%%で遅延展開を代替する。」

でも、CMDと%%を使うと、IF文を遅延展開できます。

IF "!x!"=="a" ECHO !x!
は、
CMD/CIF "%%x%%"=="a" ECHO %%x%%

IF "!x!"=="a" GOTO :TOP
は、
CMD/CIF "%%x%%"=="a" EXIT 1
IF ERRORLEVEL 1 GOTO :TOP

FORコマンドのバグ?

FOR /F "usebackq delims=;" %%1 IN ('a a;b b;c c') DO ECHO %%1

は期待したとおり動きません。

FOR /F "usebackq delims=;" %%1 IN ('a a^;b b^;c c') DO ECHO %%1

とすれば期待通り動きます。

つまり、FOR文の()の中は、最初に、区切り文字の=;,を空白に置換するようです。エスケープされてない場合です。

なので、
FOR /F IN ('コマンド')
FOR /F "usebackq" IN ('文字列')
FOR /F "usebackq" IN (`コマンド`)
の構文で、中に=;,を含む可能性があるときは、遅延展開を使うとよいでしょう。

SETLOCAL ENABLEDELAYEDEXPANSION
SET X=a a;b b;c c
FOR /F "usebackq delims=;" %%1 IN ('!X!') DO ECHO %%1

または
SET X=a a;b b;c c
FOR /F "delims=;" %%1 IN ('ECHO %%X%%') DO ECHO %%1

コマンドの中に"がない場合、かつ、コマンドと同名のファイルがない場合は、
FOR /F IN ('"コマンド"')
FOR /F "usebackq" IN (`"コマンド"`)
でもエスケープできます。

また、
FOR /F IN ("文字列")
FOR /F IN ('"コマンド"')
FOR /F "usebackq" IN (`"コマンド"`)
の構文でも、中に"があると、""のエスケープ区間が逆転したり、^のエスケープが無効になるので、この場合も、遅延展開を使ったほうがよいでしょう。

環境変数のPATHを行分けして表示するバッチファイル

ECHO %PATH%でも表示されますが、;区切りの1行なので、とても見難い。
そこで、;で行分けして表示します。

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:LOOP
FOR /F "usebackq delims=; tokens=1*" %%1 IN ('!PATH!') DO (
ECHO %%1
SET PATH=%%2
IF DEFINED PATH GOTO LOOP
)

または、

@ECHO OFF
SETLOCAL
:LOOP
FOR /F "delims=; tokens=1*" %%1 IN ('ECHO %%PATH%%') DO (
ECHO %%1
SET PATH=%%2
IF DEFINED PATH GOTO LOOP
)

2007年2月14日 (水)

HTMLファイルにドロップで引数を渡す。

HTAファイルと違って、
HTMLファイルそのものにはドロップで引数を渡すことはできませんが、
バッチファイルやショートカットを作れば、それっぽいことができます。

バッチファイルなら、
START IExplore.exe file://フルパス\CsvView.HTM?%*

ショートカットなら、
RunDLL32.EXE Shell32.DLL,ShellExec_RunDLL IExplore.exe file://フルパスv\CsvView.HTM?

<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">
<TITLE>CsvView.HTM</TITLE>
<OBJECT ID="TDC" WIDTH=0 HEIGHT=0 CLASSID="CLSID:333C7BC4-460F-11D0-BC04-0080C7055A83">
<PARAM NAME="UseHeader" VALUE="true">
<PARAM NAME="Charset" VALUE="shift_jis">
<PARAM NAME="CaseSensitive" VALUE="false">
</OBJECT><SCRIPT LANGUAGE="VBScript">
Option Explicit
Dim arg
arg=location.search
arg=Mid(arg,2)
arg=unescape(arg)
arg=Trim(Replace(arg,Chr(34),Empty))
If arg="" Then
  alert "CSV file name missing."
  close
Else
  TDC.DataURL=arg
End If

Sub window_onload()
Dim RS
Dim HTML
Dim Field
document.title=document.title & " - " & TDC.DataURL
Set RS=TDC.recordset
HTML="<" & "TABLE DATASRC=""#TDC"" BORDER><" & "THEAD><" & "TR>"
For Each Field In RS.Fields
  HTML=HTML & "<" & "TD>" & Field.Name & "<" & "/TD>"
Next
HTML=HTML & "<" & "/TR><" & "/THEAD><" & "TBODY><" & "TR>"
For Each Field In RS.Fields
  HTML=HTML & "<" & "TD><" & "SPAN DATAFLD=""" & Field.Name & """><" & "/SPAN><" & "/TD>"
Next
HTML=HTML & "<" & "/TR><" & "/TBODY><" & "/TABLE>"
document.body.innerHTML=HTML
End Sub
</SCRIPT></HEAD><BODY ></BODY></HTML>

CSVファイルを表形式で表示する。

Start CsvView.HTA CSVファイル

<HTML><HEAD><hta:application id="hta"></hta:application>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">
<TITLE>CsvView.HTA</TITLE>
<OBJECT ID="TDC" WIDTH=0 HEIGHT=0 CLASSID="CLSID:333C7BC4-460F-11D0-BC04-0080C7055A83">
<PARAM NAME="UseHeader" VALUE="true">
<PARAM NAME="Charset" VALUE="shift_jis">
<PARAM NAME="CaseSensitive" VALUE="false">
</OBJECT><SCRIPT LANGUAGE="VBScript">
Option Explicit
Dim arg
Dim fQuoting
Dim k
fQuoting=False
arg=hta.commandline
For k=1 To Len(arg)
  Select Case Mid(arg,k,1)
  Case Chr(34) fQuoting=Not fQuoting
  Case Chr(32) If Not fQuoting Then Exit For
  End Select
Next
arg=Mid(arg,k+1)
arg=Trim(Replace(arg,Chr(34),Empty))
If arg="" Then
  alert "CSV file name missing."
  close
Else
  TDC.DataURL=arg
End If

Sub window_onload()
Dim RS
Dim HTML
Dim Field
document.title=document.title & " - " & TDC.DataURL
Set RS=TDC.recordset
HTML="<" & "TABLE DATASRC=""#TDC"" BORDER><" & "THEAD><" & "TR>"
For Each Field In RS.Fields
  HTML=HTML & "<" & "TD>" & Field.Name & "<" & "/TD>"
Next
HTML=HTML & "<" & "/TR><" & "/THEAD><" & "TBODY><" & "TR>"
For Each Field In RS.Fields
  HTML=HTML & "<" & "TD><" & "SPAN DATAFLD=""" & Field.Name & """><" & "/SPAN><" & "/TD>"
Next
HTML=HTML & "<" & "/TR><" & "/TBODY><" & "/TABLE>"
document.body.innerHTML=HTML
End Sub
</SCRIPT></HEAD><BODY ></BODY></HTML>

これを、SendToフォルダに入れておくか、CSVファイルに関連付けておくとよいでしょう。

MSHTA.EXE "フルパス\CsvView.HTA" "%1"

関連付けファイルのショートカットの引数がドロップで消えないようにする。

関連付けファイル、例えば、「ARGS.VBS」のショートカットに引数「a b c」があるとき、
ARGS.VBS a b c
関連付けファイルのショートカットに「ファイル」をドロップすると、
引数「a b c」が消えて、代わりに、「ファイル」だけが引数になります。
ARGS.VBS ファイル

これを防ぐには、関連付けを展開して、アプリのショートカットに変えます。
WScript.exe ARGS.VBS a b c
アプリのショートカットに「ファイル」をドロップすると、
引数「a b c」に「ファイル」が追加されます。
WScript.exe ARGS.VBS a b c ファイル

もうひとつの方法は、関連付けを展開しないで、アプリのショートカットに変えます。
RunDLL32.EXE Shell32.DLL,ShellExec_RunDLL ARGS.VBS a b c

2007年2月13日 (火)

ファイルのリネーム、大文字/小文字の変更は?

Scripting.FileSystemObjectでリネームを、
File.Name="名前"
とした場合、大文字/小文字の違いだけだとエラーになります。

エラー: 既に同名のファイルが存在しています。
コード: 800A003A
ソース: Microsoft VBScript 実行時エラー

一度、別の名前に変えた上で、直さなければなりません。
これはアトミシティのない嫌な処理です。:-(

Shell.Applicationで、
FolderItem.Name="名前"
なら、エラーになりません。

また、Scripting.FileSystemObjectでリネームした場合、
エクスプローラのフォルダウィンドウ上では、旧項目が削除されて抜け、
新項目が作成されて末尾に追加されたように見えますが、
Shell.Applicationでリネームすれば、項目はそのままの場所で、
名前だけが変わったように見えます。

2007年2月12日 (月)

Folder.TitleやFolderItem.Nameはファイル名と違って一意ではありません。

ファイル名は一意ですが、Folder.TitleやFolderItem.Nameは一意ではありません。
「フォルダオプション」-「表示」の「登録されている拡張子は表示しない」や
拡張子/ファイルタイプのNeverShowExt値に依存して拡張子が表示されないことがあり、
それに依存して、Folder.TitleやFolderItem.Nameで重複が発生します。

NeverShowExt値は、ショートカットなどに付いています。
なので、通常、.lnkや.urlは表示されません。
つまり、hoge.txt.lnkとhoge.txtは共にhoge.txtと表示されます。

Set FolderItem=Folder.ParseName(ファイル名)
または、
Set FolderItem=Folder.Items.Item(ファイル名)
で、一意にFolderItemが特定できます。
違いは、見つからないとき、前者がNothing、後者がエラーになります。

FileName=FileSystemObject.GetFileName(FolderItem.Path)
または、
FileName=Mid(FolderItem.Path,InStrRev(FolderItem.Path,"\")+1)
で、ファイル名が取り出せます。

2007年2月11日 (日)

IEやExcelなど、PATHにないアプリを起動するバッチやショートカットの作り方

IExplore.exeやExcel.exeは、PATH配下にありません。
なので、ファイル名だけではコマンド起動やショートカットが作れません。

だからと言って、フルパスを指定するのも大変だし、
第一、インストール先がシステムやバージョンによって異なります。

幸いなことに、IExplore.exeやExcel.exeなどは、レジストリの
HKLM\Software\Microsoft\Windows\CurrentVersion\App Pathsキー配下に
登録されているため、
 STARTコマンド
 「ファイル名を指定して実行」、
 WScript.ShellのRun()
などからは、ファイル名だけで起動できます。

そこで、コマンドプロンプトやバッチファイルでは
START Excel.exe ...を使えばよいでしょう。

ショートカットにする場合は、
CMD.EXE /C START Excel.exe ...のようなショートカットを作って、
最小化にしておくとよいでしょう。

もし、タスクバーにアイコンが一瞬現れるのが嫌なら、
RunDLL32.EXE Shell32.DLL,ShellExec_RunDLL Excel.exe ...
のようなショートカットを作るとよいでしょう。

2007年2月10日 (土)

バッチファイルからコンソールウィンドウを最小化する。

コンソール最小化.CMD

@ECHO OFF
SETLOCAL
MORE +10 "%~f0" >"%~f0.vb"
SET DOTNET=%SystemRoot%\Microsoft.NET\Framework
FOR /F "delims=" %%1 IN ('DIR /AD /B /ON "%DOTNET%\v*"') DO IF EXIST "%DOTNET%\%%~1\vbc.exe" SET DOTNET=%DOTNET%\%%~1\vbc.exe
"%DOTNET%" /nologo "%~f0.vb"
DEL "%~f0.vb"
"%~f0.exe"
DEL "%~f0.exe"
GOTO :EOF
Public Class Class1
Private Declare Auto Function GetConsoleTitle Lib "kernel32.dll" (lpConsoleTitle As System.Text.StringBuilder, nSize As Integer) As Integer
Private Declare Auto Function FindWindow Lib "user32.dll" (className As String, WindowsName As String) As Integer
Private Declare Function ShowWindow Lib "user32.dll" (hwnd As Integer, nCmdShow As Integer) As Integer
Public Shared Sub Main()
Dim lpConsoleTitle As New System.Text.StringBuilder(1024)
GetConsoleTitle(lpConsoleTitle,1024)
ShowWindow(FindWindow(Nothing,lpConsoleTitle.ToString()),6)
End Sub
End Class

よく使うなら、exeにして、使ってください。
応用としては、非表示にして実行して、終わったら表示するなんてことも。

2007年2月 9日 (金)

コマンドラインでショートカットを作成する。

以下のバッチファイルで、「ファイル へのショートカット.lnk」ができます。

ショートカットの作成.cmd ファイル

@if(0)==(0) ECHO OFF
CScript.exe //NoLogo //E:JScript "%~f0" "%~dp1" "%~nx1"
GOTO :EOF
@end
var FolderItem=new ActiveXObject('Shell.Application').NameSpace(WScrip
t.Arguments.Item(0)).Items().Item(WScript.Arguments.Item(1));
FolderItem.InvokeVerb('ショートカットの作成(&S)');

2007年2月 8日 (木)

テキストファイルの文字コードを自動判定する。

テキストファイルの文字コードを自動判定する。

文字コード.CMD ファイル

@if(0)==(0) ECHO OFF
REN "%~f1" "%~nx1.txt"
CScript.exe //NoLogo //E:JScript "%~f0" "%~f1.txt"
REN "%~f1.txt" "%~nx1"
GOTO :EOF
@end
var htmlfile=WScript.GetObject(WScript.Arguments.Item(0),'htmlfile');
while(htmlfile.readyState!='complete') WScript.Sleep(100);
WScript.Echo(htmlfile.charset);

2007年2月 7日 (水)

「コマンドプロンプトで開く」のウィンドウタイトルを変える。

ディレクトリに「コマンドプロンプトで開く」や
ファイルに「ひとつ上をコマンドプロンプトで開く」に関連付けていると、
コマンドプロンプトのウィンドウタイトルがみんな同じで区別の付かない
「C:\WINDOWS\system32\cmd.exe」になります。

そこで、これを開いたときのカレントディレクトリ名に変えましょう。

関連付けを以下のように変えます。

[HKEY_CLASSES_ROOT\Directory\shell\CommandPrompt]
@="コマンドプロンプトで開く"
[HKEY_CLASSES_ROOT\Directory\shell\CommandPrompt\Command]
@="CMD.EXE /KCD %1 & TITLE %1"

[HKEY_CLASSES_ROOT\*\Shell\CommandPrompt]
@="ひとつ上をコマンドプロンプトで開く"
[HKEY_CLASSES_ROOT\*\Shell\CommandPrompt\Command]
@="CMD.EXE /KCD %1\\.. & TITLE %%CD%%"

2007年2月 6日 (火)

普通の方法でHTMLソースが得られないときに、HTMLソースを取り出す奥の手

ダイアログウィンドウなど、HTMLで作られていると分かっていても、
「名前を付けて保存」や「ソースの表示」などが使えなくて、
そのHTMLソースを得る方法がないとき、どうするか?
もし、そのウィンドウがCTRL+Pで印刷できるなら、HTMLソースが取れます。

そのウィンドウにCTRL+Pしてみます。
もし、そこで印刷ダイアログが出れば、HTMLソースが取れます。
※ひょっとして、IEのバージョンに依存するかも知れません。

「印刷」または「印刷プレビュー」ダイアログの表示中は、
テンポラリフォルダ
C:\Documents and Settings\ユーザ名\Local Settings\Temp\
に、
7Z54OAUZ.htm
のような名前のファイルができます。更新日時順に表示して、たぶん最新です。
ダイアログを閉じると削除されます。
なので、ダイアログ表示中に、ファイルをコピーするとよいでしょう。

2007年2月 5日 (月)

IEの「ソースの表示」で文字化けしないでオリジナルソースを保存する。

IEで「ソースを表示」すると、「メモ帳」にオリジナルソースが表示されます。
しかし、「メモ帳」で扱えない文字コードやバイナリは当然、文字化けします。

文字化けしたときは、「メモ帳」の「名前を付けて保存」を開きます。
そこで、FileNameが分かります。それをクリップボードにコピーします。
次に「名前を付けて保存」をCacheフォルダに移動します。
それにはちょっとコツが必要です。

ファイル名欄に、
C:\Documents and Settings\ユーザ名\Local Settings\Temporary Internet Files\*
を入れてEnterキー。

或いは、上から順に辿ると、
C:\Documents and Settings\ユーザ名\Local Settingsへ行っても、
一覧にTemporary Internet Filesが見当たりません。
ここで、ファイル名に*を入れてEnterキーすると表示されます。

Temporary Internet Filesを選択して、ファイル名にTemporary Internet Files\*
を入れてEnterキーするとファイル一覧が表示されます。

ファイル名に先ほどのFileNameを入れて、ここでも、ワイルドカードを使って、
FileName* のように入れてEnterキーすると、一覧にそのファイルが表示されます。

後は、そのファイルをドラッグや右クリックして好きなようにしてください。

2007年2月 4日 (日)

フォルダペインのバックグラウンドのコンテキストメニューに追加する。

フォルダペインのバックグラウンド(背景)を右クリックしたときの
コンテキストメニューにメニュー項目名を追加する方法は、
HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers
にありそうですが、難しそうなので、もっと簡単に出来そうな代替方法を。

「新規作成」サブメニューを利用します。

適当な拡張子にShellNewキーを付けて、command値にコマンドラインを
書いておけばよいのです。

例えば、

Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.vbs\ShellNew]
"command"="WScript.exe \"C:\\hoge\\hoge.VBS\" \"%1\" %2!d!"

C:\フォルダ\ で「新規作成」サブメニューの「VBScript Script File」を実行すると、
hoge.VBSに以下の引数が渡ります。

"%1" "C:\フォルダ\新規VBScript Script File.vbs"
"%2!d!" 65698

ここで、「VBScript Script File」は拡張子「.vbs」に関連付けられた
ファイルタイプ「VBSFile」の名前(HKCR\VBSFileキーの@値)です。

架空の拡張子とファイルタイプを作れば、任意のメニュー項目名が作れます。

※Vistaでは、背景メニューが簡単に作れます。
HKEY_CLASSES_ROOT\Directory\Background\shell\

2007年2月 3日 (土)

ショートカットのショートカットを作る。

普通、ショートカットのショートカットは作れませんが、

RunDLL32.EXE SHELL32.DLL,ShellExec_RunDLL c:\hoge\hoge.lnk [引数...]

なら作れます。

オプション引数などを指定したアプリのショートカットに、更に加えて、
オプションやファイルなどの引数を指定したショートカットが作れます。
そのショートカットに更にドロップでファイルを渡すことも。。。

2007年2月 2日 (金)

ATコマンドやタスクスケジューラのコマンドの指定は?

仕様の説明がないようで、困ったものです。仕様がないので、験してみました。

hoge
拡張子がないときは、拡張子.exeを付けて、hoge.exeをPATHで検索。引数は有効。

{hoge.com|hoge.exe|hoge.bat|hoge.cmd}
拡張子が{.com|.exe|.bat|.cmd}のときは、その名前をPATHで検索。引数は有効。

hoge.vbs
拡張子が{.com|.exe|.bat|.cmd}以外のときは、その関連付けを調べて、
hoge.vbsのまま関連付けを展開実行して、終了同期する。引数は無視。

アプリ{.com|.exe}やバッチファイル{.bat|.cmd}は引数が有効。
関連付けは引数を無視。
なので、関連付けで引数を指定するときは、アプリ起動に変える必要があります。
wscript.exe hoge.vbs 引数...

作業フォルダのデフォルトはC:\Windows\System32

2007年2月 1日 (木)

ATコマンドやタスクスケジューラでショートカット(リンク)を実行する。

ATコマンドやタスクスケジューラで、アプリやバッチファイルを実行するとき、
ウィンドウの大きさや作業ディレクトリなどを指定したい。

と思っても、ショートカット(リンク)ファイルはそのままでは指定できません。

ならば、

RunDLL32.EXE URL.DLL,FileProtocolHandler c:\hoge\hoge.lnk

RunDLL32.EXE SHELL32.DLL,ShellExec_RunDLL c:\hoge\hoge.lnk [引数...]

ただし、実行結果の記録が残りません。起動しっ放しになります。

もし実行結果の記録を残すのなら、ショートカット(リンク)ファイルの
代わりにWSHスクリプトファイルを作って、そこから、WScript.Shellの
Run()でウィンドウの大きさを指定して、同期実行するしかないでしょう。
必要なら、WScript.ShellでCurrentDirectoryも変更して。

そういう汎用のスクリプトもあります。
コマンドラインからWScript.ShellのRun()を呼び出すVBScript
WScript.exe ShellRun.VBS [/D:作業ディレクトリ] [/S:表示] [/W] ファイル [引数...]
これなら非表示も可能です。

ただし、間接起動の場合、タスクの終了が子孫まで届きません。

« 2007年1月 | トップページ | 2007年3月 »