最終更新: twoflat1017 2014年06月23日(月) 21:54:59履歴
(一部編集中)
WindowsXPのサポート終了に伴い、業務で使うパソコンがWindows7とInternetExplorer8になり、旧環境で問題なく動作していたVBScriptが新環境でまったく動かなくなった。それに関する覚書である。
VBScriptでIEを操作するスクリプトは、ここにあるイベントを捕捉する仕組みを利用し、DocumentCompleteイベントなどをトリガにして目的の作業を行うように実装していた。これがなぜIE8になってから動かなくなったのか?をWebで調査したところ、セキュリティ向上のため、IEの動作仕様が変わった、というのが理由と分かってきた。なぜ動かなくなったのか、IE動作仕様変更、などは補足に譲るとして、実際に行うことは、
- Windowsのレジストリに、整合性レベル中を意味するIEを別名として登録する
- スクリプト中の、CreateObjectの引数に上記整合性レベル中のIEを指定するように修正する
これには、
- スクリプトでレジストリ読み書き
- レジストリファイルをエクスプローラ等から実行
- レジストリエディタで手動で編集
スクリプト中の、IE起動前にレジストリに必要な記載があるかどうかの判定および、記載がいない場合にレジストリに記載を追記する処理となるよう、以下のコードを適切な箇所に追加する。ただし、Windows7からレジストリ編集のコードを実行するには、スクリプト内で管理者権限への昇格が必要である。必ず昇格させるようにしたほうが無用のエラーは防げそうだが、WSH起動後に32ビット版で再起動するコードを書き換えて、スクリプト開発者に選択させる拡張性を持たせてもいいかもしれない。
編集中)
編集中)
以下のコードを適当なファイル名のテキストファイルに保存し、実行する。
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\InternetExplorer.ApplicationMedium] [HKEY_CLASSES_ROOT\InternetExplorer.ApplicationMedium\CLSID] @="{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}"*1
- Windowsキー+R→regeditを入力しエンター
- HKEY_CLASSES_ROOTで右クリック→新規→キーを選択
- 新しく作成されたキーの名称をInternetExplorer.ApplicationMediumに変更
- InternetExplorer.ApplicationMediumで右クリックし→新規→キーを選択
- 新しく作成されたキーの名称をCLSIDに変更
- CLSIDをアクティブにした状態で右ペインの(規定)で右クリック→修正を選択
- {D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}
イベント捕捉のこれまでのコード
Set IE = CreateObject("InternetExplorer.Application", "IE_")を以下に示すような
Set IE = CreateObject("InternetExplorer.ApplicationMedium", "IE_")に書き換える。WinXPとWin7、IE7と8等でも動くことを意図するならば、応用として、OSとIEバージョンを取得してそれに応じたコードにするのが良さそう。
スクリプトに上記変更を入れないまま実行すると、スクリプトがQuitイベントを捕捉して終了してしまうため。
'OnQuitイベント Sub IE_OnQuit() objLogFile.Write 1, "Internet Explorerが閉じられました。" 'オブジェクトの破棄 Set objIE = Nothing WScript.Quit() 'スクリプトの終了 End Subこれは、ユーザ操作によりIEがクローズされた場合にスクリプトだけが残ってしまう(スクリプトを実行するプロセスが残ってしまう)ことに対応するため、Quitイベントを捕捉した場合、スクリプトは終了するようにしていた。WinXP+IE7ではこれまで、Quitイベントを捕捉することはなかった。
これについての直接の記事はないものの、この記事と和訳されたこの記事にある、
- IE のインスタンスがインターネット (保護モード、LowIL) とイントラネット (非保護モード、MediumIL) の間を遷移すると、Internet Explorer は遷移を新しいプロセスでハンドルする必要があります。
- 多くのシナリオへの互換性のため、Internet Explorer は既定のタブ プロセスを整合性低のタブであるとみなしています。したがって Internet Explorer が COM オートメーションにより生成される際、タブ プロセスの既定は整合性低のタブになります。ブラウザーはページ遷移により整合性中のタブ コンテンツ プロセスが必要であると判断すると、仮想タブ切り替えが実行されます
- イントラネットサイトにアクセスを開始すると、IEは仮想タブへの切り替えを行う
- 切り換え時、IEはそれまで起動していた整合性低のタブを一旦停止させ、整合性中のタブを起動する
- 一旦停止の結果、IEはQuitイベントを発報する
結局のところ、上記方法に落ち着いたのだが、この記事には動作仕様変更に対して、
- モニカーを使った構文
- NewProcess イベント をトラップして適切に対処する
Set IE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")では、GetObjectを使用しており、CreateObjectで指定可能なイベント捕捉に重要な第2引数が存在しない。すなわち、イベント捕捉ができないのではないだろうか。また、NewProcessイベントをトラップすることも同様に、NewProcessイベントをトラップして、引数にあるブラウザオブジェクトをスクリプト内に用意した変数にSetする、までは良さそうだが、Setしたブラウザオブジェクトのイベント捕捉ができないスクリプトに戻ってしまいそうで、これも採用できない。
タグ
コメントをかく