« 2009年5月 | トップページ | 2009年7月 »

2009年6月19日 (金)

Adobe Readerはマルチインスタンスサーバです。

Adobe Readerはサーバなんですね。だから、1プロセスが基本形。
なので、AcroRD32.exeを複数、起動しても、1プロセスになります。
2番手以降はクライアント、1番手のサーバに処理を依頼して、完了を待たず、即終了。
逆に印刷が完了しても、1プロセスの場合は終了しないで、サーバとして居座ります。

これらの特性に逆らうには、/nで別プロセスにする。
印刷完了でプロセスを終了させるには、先にプロセスを1個起こしておいて、/n /tで印刷する。
印刷完了でプロセスが終了した後に、先に起こしたプロセスを終了させる。
もし、/nがないと、1番手のサーバに処理を依頼して、即終了するため、印刷完了の待ち合わせができません。
そのため、複数ファイルを連続印刷すると、印刷処理が集中してパンクしたり、順番が不定になったりします。
もし、先にプロセスを1個起こしておかないと、印刷が完了しても、そのプロセスが終了しないため、永久に待ちが解けません。

ところで、Adobe Reader 9からインプロセスサーバに変わりました。

Adobe Reader 8までは、アウトプロセスサーバだったので、IEでPDFファイルを開くと、AcroRD32.exeのプロセスができましたが、Adobe Reader 9からはインプロセスサーバに変わったので、AcroRD32.exeのプロセスはできません。
例えば、GetObject(PDFファイル)で、AcroRD32.exeのプロセスができることを期待していると、外れます。

2009年6月18日 (木)

バッチファイルで複数のPDFファイルを連続印刷する。(その3)

XP Home Editionの場合は、WSHでやるのが素直ですが、無理矢理バッチでやると。

PdfPrintHE.CMD PDFファイル...(複数可、ワイルドカード可)

@echo off
setlocal
set ACTIVE=
for /f %%I in ('start /min /b /wait mshta.exe vbscript:execute("createobject(""scripting.filesystemobject"").getstandardstream(1).write createobject(""wscript.shell"").appactivate(""adobe reader""):close:"^)') do set ACTIVE=%%I
if /i %ACTIVE%==true goto :STARTED
START ACRORD32.EXE /n /h
:STARTING
for /f %%I in ('start /min /b /wait mshta.exe vbscript:execute("createobject(""scripting.filesystemobject"").getstandardstream(1).write createobject(""wscript.shell"").appactivate(""adobe reade""):close:"^)') do if /i %%I==false goto :STARTING
:STARTED
for %%I in (%*) do START /WAIT ACRORD32.EXE /n /t %%I
if /i %ACTIVE%==false start /min /b /wait mshta.exe vbscript:execute("set wshell=createobject(""wscript.shell""):if wshell.appactivate(""adobe reade"") then wshell.sendkeys ""^q"":close:")

ここで、
appactivate("adobe reader")

appactivate("adobe reade")
の微妙な違いには意味があります。後者は前方一致です。

2009年6月17日 (水)

バッチファイルで複数のPDFファイルを連続印刷する。(その2)

XP Pro以上なら、

PdfPrintXP.CMD PDFファイル...(複数可、ワイルドカード可)

@echo off
setlocal
set /a n=0
for /f "skip=1 delims=" %%I in ('tasklist /nh /fi "imagename eq acrord32.exe"') do set /a n+=1
if not %n%==0 goto :STARTED
START ACRORD32.EXE
:STARTING
ping -n 2 localhost >NUL
for /f "skip=1 delims=" %%I in ('tasklist /nh /fi "windowtitle eq Adobe Reader" /fi "imagename eq acrord32.exe"') do goto :STARTED
goto :STARTING
:STARTED
for %%I in (%*) do START /WAIT ACRORD32.EXE /n /t %%I
if %n%==0 taskkill /im ACRORD32.EXE

アプリがしっかり立ち上がるのを待ち合わせる必要があります。

2009年6月16日 (火)

バッチファイルで複数のPDFファイルを連続印刷する。

/pの場合は、コマンドで印刷完了の待ち合わせができないので、1コマンドで複数ファイルを指定しちゃいます。

START ACRORD32.EXE /p /h "ファイル1" "ファイル2" ...

/tの場合は、1ファイル1コマンドで待ち合わせします。

START ACRORD32.EXE
START /WAIT ACRORD32.EXE /n /t "ファイル1"
START /WAIT ACRORD32.EXE /n /t "ファイル2"
...

最終的にアプリが1個残ります。

XP Pro以上なら、

setlocal
set /a n=0
for /f "skip=1 delims=" %%I in ('tasklist /nh /fi "imagename eq acrord32.exe"') do set /a n+=1
if %n%==0 START ACRORD32.EXE & ping -n 2 localhost >NUL
START /WAIT ACRORD32.EXE /n /t "ファイル1"
START /WAIT ACRORD32.EXE /n /t "ファイル2"
...
if %n%==0 taskkill /im ACRORD32.EXE

XP Home Editionの場合は、TLIST.EXEとKILL.EXEを入手して代替するか、WSHで。

2009年6月11日 (木)

260文字以上の長いパス名を短いパス名に変える。

例えば、fso.GetFile("長いパス名").ShortPath で簡単に短いパス名に変えられそうですが、fso.GetFile("260文字以上の長いパス名").ShortPath はエラーになって使えません。
そこで、ディレクトリ階層を上に遡って、上から順に短くして行きます。

Set fso=CreateObject("Scripting.FileSystemObject")

MsgBox GetShortPathName("長~いパス名")

Function GetShortPathName(Path)
GetShortPathName=Path
If Len(Path)>259 Then
  GetShortPathName=fso.BuildPath(GetShortPathName(fso.GetParentFolderName(Path)),fso.GetFileName(Path))
  If Len(GetShortPathName)>259 Then Exit Function
End If
If fso.FileExists(GetShortPathName) Then
  GetShortPathName=fso.GetFile(GetShortPathName).ShortPath
Else
  GetShortPathName=fso.GetFolder(GetShortPathName).ShortPath
End If
End Function

2009年6月10日 (水)

「名前を付けて画像を保存」するコンテキストメニュー拡張(その2)

画像のプロパティからURLをコピーして、URLを指定して画像を開き、「名前を付けて保存」しても、ダメな場合は、
<a href=URL>ほげ</a>
というhtmlファイルを作成して、開き、右クリックして「対象を保存」します。
これはさらに面倒なので、コンテキストメニューを拡張します。

SaveAsImg2.htm

<script language=vbscript defer>
If UCase(external.menuArguments.event.srcElement.tagName)="IMG" Then
  set a1=external.menuArguments.document.createElement("A")
  external.menuArguments.event.srcElement.applyElement a1
  a1.href=external.menuArguments.event.srcElement.src
  a1.focus
  CreateObject("WScript.Shell").SendKeys "+{f10}a"
End If
</script>

SaveAsImg2.reg

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\名前を付けて画像を保存(&2)]
@="C:\\どこか\\SaveAsImg2.htm"
"Contexts"=dword:00000002

これは、<img src=URL> を <a href=URL><img src=URL></a> に書き換えて、画像の右クリックで「対象を保存(&A)」します。

※ 保護モード有効のページではSendKeys()がNOP。

2009年6月 9日 (火)

「名前を付けて画像を保存」するコンテキストメニュー拡張

画像の右クリックで「名前を付けて画像を保存」が、オリジナルの名前と形式でなく、「無題.bmp」や「untitled.bmp」に化けてしまうことがあります。
これは<img src=URL>のURLでキャッシュを探して見つからないときにそうなります。
そのような場合、画像のプロパティからURLをコピーして、アドレスバーに張り付けて開き、「名前を付けて保存」すれば、オリジナルの名前と形式で保存できます。※ダメなときもあります。
それは面倒なので、コンテキストメニューを拡張します。

SaveAsImg1.htm

<script language=vbscript defer>
If UCase(external.menuArguments.event.srcElement.tagName)="IMG" Then
  Set ie=CreateObject("InternetExplorer.Application")
  ie.Navigate "about:blank"
  Do While ie.Busy Or ie.ReadyState<>4
  Loop
  ie.Navigate external.menuArguments.event.srcElement.src
  Do While ie.Busy Or ie.ReadyState<>4
  Loop
  Const OLECMDID_SAVEAS=4
  Const OLECMDEXECOPT_PROMPTUSER=1
  ie.ExecWB OLECMDID_SAVEAS,OLECMDEXECOPT_PROMPTUSER
  ie.Quit
End If
</script>

SaveAsImg1.reg

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\名前を付けて画像を保存(&1)]
@="C:\\どこか\\SaveAsImg1.htm"
"Contexts"=dword:00000002

これは、画像をIEで開いて、「名前を付けて保存」します。

※ 保護モード有効のページではCreateObject()がエラー。

2009年6月 8日 (月)

「名前を付けて画像を保存」で日本語ファイル名が「untitled.bmp」や「無題.bmp」に化ける。

IE9ではuntitled.pngや無題.png。

<img src="http://~/日本語.jpg">のようにURLに日本語が含まれる場合は、クライアントの送り方とサーバの受け取り方に選択肢があるため、合わないと表示ができません。
表示はできても、「名前を付けて画像を保存」すると、日本語ファイル名が「untitled.bmp」や「無題.bmp」に化けることがあります。
これは、たぶん、IEが「名前を付けて画像を保存」するときに、シフトJISのURLでキャッシュを探すせいだろうと想像してます。

で、対処法の一つは、URLをUTF-8のURLエンコードすることですが、その場合、「名前を付けて画像を保存」すると、日本語ファイル名が短いファイル名になります。

なので、URLに日本語を使うときは、<a href=URL><img src=URL></a> のように、<a href=URL>を併用するとよいでしょう。
これなら、「名前を付けて画像を保存」の代わりに「対象を保存」で、日本語ファイル名で保存できます。

2009年6月 7日 (日)

「名前を付けて画像を保存」でファイル名が「untitled.bmp」や「無題.bmp」に化ける。

IE9ではuntitled.pngや無題.png。

何らかの理由で、<img src=URL>のURLがキャッシュに見つからないときに、そうなるようです。
(a) キャッシュが壊れている。
→ キャッシュを削除する。
→ URLを開いて「名前を付けて保存」する。
(b) キャッシュが溢れている。開いた直後は正しいのに時間が経つと化ける。
→ キャッシュを削除する。拡張する。
→ URLを開いて「名前を付けて保存」する。
(c) URLがhttps:のとき。「暗号化されたページをディスクに保存しない」設定で。
→ <a href=URL>に変えて「対象を保存」する。
(d) URLが変換される。例えば、MSDNライブラリなどのms-help:は、キャッシュではms-itss:になる。
→ <a href=URL>に変えて「対象を保存」する。
(e) ファイル名に日本語が使われている。
→ <a href=URL>に変えて「対象を保存」する。

参考:

http://support.microsoft.com/kb/810978/ja
Internet Explorer で画像がビットマップ (.bmp ファイル) として保存される
この現象は、破損しているプログラム ファイル (たとえば、ActiveX または Java のオブジェクト) がハード ディスクの SystemRoot\Downloaded Program Files フォルダにダウンロードされている場合に発生することがあります。

http://support.microsoft.com/kb/880559/ja
インターネットのページ (Web ページ) 上の JPEG 形式の画像が BMP 形式でしか保存できない場合の対処方法
インターネット一時ファイルや履歴を削除することによって、問題を解決できる可能性があります。

http://support.microsoft.com/kb/260650/ja
Internet Explorer でグラフィック データ ファイルが適切な形式で保存されない
一時インターネット ファイルのキャッシュがいっぱいになっている場合
[インターネット オプション] ダイアログ ボックスの [詳細設定] タブにある [暗号化されたページをディスクに保存しない] チェック ボックスがオンで、セキュリティで保護された接続 (https) を使用してページを読み込んでいる場合

2009年6月 6日 (土)

インターネットショートカット(.url)でWebページを疑似最大化で開く。

スクリプトで最大化と同じウィンドウの位置と大きさに変更するhtmlファイルを利用します。

maximize.htm

←ここにMark Of The Web行を置く。
<script language=vbscript>
moveTo 0,0
resizeTo screen.availWidth,screen.availHeight
navigate Mid(location.search,2)
</script>

インターネットショートカットを以下のように変更します。
[InternetShortcut]
URL=URL

[InternetShortcut]
URL=file:///C:/どこか/maximize.htm?URL

ただし、マイコンピュータゾーンでは、スクリプトがブロックされるので、もし、インターネットゾーンが許しているなら、インターネットのMark Of The Web行を先頭に追加します。
<!-- saved from url=(0014)about:internet -->
さもなく、もし、イントラネットゾーンが許しているなら、イントラネットのMark Of The Web行を先頭に追加します。
<!-- saved from url=(0017)http://localhost/ -->
それも駄目なら、信頼済みサイトゾーンで、

maximize.mht

MIME-Version: 1.0
Content-Type: text/html
Content-Location: http://windowsupdate.microsoft.com/

<script language=vbscript>
moveTo 0,0
resizeTo screen.availWidth,screen.availHeight
navigate Mid(location.search,2)
</script>

[InternetShortcut]
URL=file:///C:/どこか/maximize.mht?URL

※それも駄目なら、イントラネットのZoneIDで、
(
Echo [ZoneTransfer]
Echo ZoneId=1
) > "maximize.htm:Zone.Identifier"


スクリプトで変更したウィンドウの位置や大きさは、レジストリに記憶されません。

2009年6月 5日 (金)

インターネットショートカット(.url)を最大化で開く。

Webページのインターネットショートカットは、START /MAX ほげほげ.url や .urlファイルの ShowCommand=3 が効きません。

コマンドラインでは、
START /MAX IExplore.exe -nohome "ほげほげ.urlのフルパス"

GUIでは、いろいろやり方がありますが、「最大化で開くIEのショートカットファイル」を使う方法。

最大化で開くIEのショートカットファイル IExplorerMax.lnk

「リンク先」「"C:\Program Files\Internet Explorer\iexplore.exe" -nohome」
「実行時の大きさ」「最大化」

(A)「最大化で開くIEのショートカットファイル」を作って、インターネットショートカットをドロップする。

(B)「最大化で開くIEのショートカットファイル」をSendToフォルダに置いて、インターネットショートカットを「送る」。

(C)「最大化で開くIEのショートカットファイル」を作って、インターネットショートカットの関連付けに追加する。

[HKEY_CLASSES_ROOT\InternetShortcut\shell\openmax]
@="最大化で開く(&X)"

[HKEY_CLASSES_ROOT\InternetShortcut\shell\openmax\command]
@="RunDLL32.EXE Shell32.DLL,ShellExec_RunDLL \"C:\\どこか\\IExplorerMax.lnk\" %1"


一般に、IEは、最大化やウィンドウの位置と大きさをレジストリに記憶して、次に開くときに復元します。
ただし、インターネットショートカット(.url)のopen動詞で開くと、これらを記憶せず、最大化も復元しません。
これは、IExplore.exe -Embedding で起動していることと関係がありそう。
-Embedding は、COMの起動方法で普通、非表示。
例えば、START /MAX IExplore.exe -Embedding すると、非表示。

2009年6月 4日 (木)

IE や Webページを最大化で開く。

START /MAX IExplore.exe や ショートカットの「実行時の大きさ」「最大化」が、効くとき と 効かないとき があります。
その違いは、別プロセスを起こすか、既存プロセスに同居するか、の違いのようです。
IE7までは、IExplore.exeで起こすと、別プロセスになりました。
しかし、IE8からは、条件により(ドメイン?)、既存プロセスに同居するようになりました。

最大化で開くIEのショートカットファイル
「リンク先」
"C:\Program Files\Internet Explorer\iexplore.exe" -nohome
または、
"C:\Program Files\Internet Explorer\iexplore.exe" -e
「実行時の大きさ」「最大化」

最大化で開くWebページのショートカットファイル

「リンク先」「"C:\Program Files\Internet Explorer\iexplore.exe" -nohome URL」
「実行時の大きさ」「最大化」

インターネットショートカット(.url)ではできないのでショートカットファイル(.lnk)に変えます。


Explorer.exeも既存プロセスに同居しますが、それでも START /MAX Explorer.exe は効きます。
なので、IE8のこの仕様は、「障害」と思います。

2009年6月 3日 (水)

メモ帳やIEなどのアプリを関連付けで開くとき、常に最大化や最小化で開く。

アプリを最大化や最小化で開くには、ショートカットファイル(.lnk)の「実行時の大きさ」を「最大化」や「最小化」にしておけばよいのですが、関連付けの場合はどうするか?

関連付けで、
cmdw.exe /c start /max "" "アプリ" %1
という方法もありますが、標準環境でやるには?

まず、アプリを最大化や最小化で開くショートカットファイル(.lnk)を作成します。
関連付けでそのショートカットファイル(.lnk)を起動します。
RunDLL32.EXE Shell32.DLL,ShellExec_RunDLL "ショートカットファイルのパス" %1

関連付けの変更箇所が結構多いのが難点かな。


メモ帳やIEなどのアプリは、最後に終了したときのウィンドウの位置や大きさを記憶しているので、それを利用した方法がよく出てますが、どうなんでしょう?
IEは「最大化」も記憶するようですが、メモ帳は「通常のウィンドウ」の位置と大きさだけみたいだし、「通常のウィンドウ」の位置と大きさを「最大化」と同じにするのは、ちょっと違うし。

2009年6月 2日 (火)

バッチファイルからMsgBox()を使う。

バッチファイルの場合は、mshta.exeが便利です。

for /f "delims=" %%I in ('start /min /b /wait MSHTA.EXE vbscript:Execute("CreateObject(""Scripting.FileSystemObject"").GetStandardStream(1).Write MsgBox(""text"",1,""title""):close"^)') do echo %%I

for /f in (' ')の中では、) は " か ^ でエスケープする必要があります。
('" "')でエスケープすることもできますが、もし、中で " を使っていると、エスケープ範囲が逆転してします。

もし、start /min /b /wait がないと、HTAウィンドウが一瞬開きます。
目立たないように、resizeTo 0,0 としても、タイトルバーが見えてしまいます。

« 2009年5月 | トップページ | 2009年7月 »