C#のProcessでIEを複数起動して、すべてのプロセスを閉じる方法
以下記事は以前に書いたCOM経由でIEを操作する方法です。
COMの記事を書いたタイミングでは、-nomergeオプションを使ってなかったのでCOMに変更して対応した。
確か、-noframemergingオプションは試したけど、これはうまくいかなかった。
でも、以下のサンプルコードでやってみると上手くいく。
ということは、後ほど記述するけど、これは起動したIEのx64,x86バージョンの違いによるものかもしれない。
今回の内容は、IE起動の起動と終了をProcess経由でやる方法です。
ただし、いくつか満たすべき条件があります。
満たすべき条件
・64bitのIEを使う必要がある
・-nomergeか-noframemerging オプションの追加が必要
・Windowが立ち上がるまで待つ必要がある。
上記条件を満たして実際に動くソースは以下です。
実験用のソースコード
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | using System; using System.Diagnostics; using System.IO; using System.Collections.Generic; using System.Threading; namespace ExperimentCsharpCode.ProcessDir.HandleIE { class OpenIE { private string _iePath = @"C:\Program Files\Internet Explorer\iexplore.exe" ; //private string _iePath = @"C:\Program Files (x86)\Internet Explorer\iexplore.exe"; private List<Process> _pList = new List<Process>(); public OpenIE() { try { //SimpleOpen(); //HandleMultiIE(); HandleMultiIEWithNoMergeArg(); ProcessCloseMainWindow(); } catch (Exception e) { Console.WriteLine(e); throw ; } } /// <summary> /// 一つだけIEを起動して閉じる。 /// </summary> public void SimpleOpen() { ProcessStartInfo pInfo = new ProcessStartInfo(_iePath, arg); var p = Process.Start(pInfo); Thread.Sleep(3000); p.CloseMainWindow(); } /// <summary> /// 複数IEを起動 /// </summary> public void HandleMultiIE() { for ( int i = 0; i < 5; i++) { ProcessStartInfo pInfo = new ProcessStartInfo(_iePath, arg); _pList.Add(Process.Start(pInfo)); Thread.Sleep(3000); } } /// <summary> /// -nomergeをつけて複数IEを起動 /// </summary> public void HandleMultiIEWithNoMergeArg() { for ( int i = 0; i < 5; i++) { ProcessStartInfo pInfo = new ProcessStartInfo(_iePath, arg); _pList.Add(Process.Start(pInfo)); Thread.Sleep(3000); } } /// <summary> /// 開いたすべてのプロセスを閉じる /// </summary> private void ProcessCloseMainWindow() { for ( int i = _pList.Count - 1; i >= 0; i--) { _pList[i].CloseMainWindow(); Thread.Sleep(3000); } } } } |
実験用ソースコードを呼び出す側
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | using System; using System.Collections.Generic; using System.Text; using ExperimentCsharpCode.LinkedList; using ExperimentCsharpCode.ProcessDir.HandleIE; namespace ExperimentCsharpCode { class Program { static void Main( string [] args) { var sample = new OpenIE(); } } } |
考察
Processをひとつだけ起動する場合は32bit,64bitどちらのケースでも-nomergeがなくてもうまく閉じれる
なぜという部分がまだよくわからない。
連続で起動した場合だと-nomerge
そもそも-nomergeとは何なのか。
こちらのサイトで詳しい説明があった。
内容を見ていると、セッションを別にするとのことだけど、
なぜセッションと複数IE起動したプロセスが変化することが関係あるのかわからなかった。
32bit,64bit IE どちらが呼ばれているかわからないパターンがある
64bitのIEを使う理由は、なぜか32bitのIEだとCloseMainWindow()でウィンドウが閉じられない。実験用のソースでコメントアウトしている_iePathの(x86)のほうをコメント解除して実行すると再現できると思います。
仮に実務で使うことを想定すると、どこかにIEの実行パスを書く必要があるのか?直感的にIEの格納パスはどのPCでも同じと思われるけど、例えば今回の例でいうと、ProgramFIleをDドライブとかにしてるとアウトですよねぇ。
ふと気づいたけど、 COM経由でIEを操作する方法の記事でProcess経由の実験コードも載せていた。
そこでは、IEを以下のように呼び出していた。
1 | var p = Process.Start("IExplore.exe", "https://www.yahoo.co.jp/"); |
これだと私の環境では32bitが呼び出されいるようだった。
恐らくこれも設定で変更可能みたいだけど、特にやってない。
この方法でやるとすると、IE側での設定が必要かもしれないなと、以下の記事を読んでいて思った。
以前書いたサンプル(WinFormで作成)だと例外が発生する
以前書いたサンプルでは、リストに格納されたプロセスに対してCloseMainWindow()すると例外が発生していた。
先ほども書いたけどもう一度。
恐らく32bitが呼び出されていたはず。
1 | var p = Process.Start("IExplore.exe", "https://www.yahoo.co.jp/"); |
っで、今回のサンプルはコンソールだったのだけど、そこでは例外が発生しなかった。
例外発生しなかったけど、開いたIEが閉じたわけでもない。
ブレークポイントで止めると、ちゃんとプロセスは存在していた。
まとめ
IEをProcessで操作したいというこだわりがあったわけでなく、なぜProcessではなく、COMを使うのかということを聞かれたため調べた。
COMは実際に実装したからよかったけど、ProcessでIEの操作は、開始早々諦めた。(複数起動だけでなく、子→孫まで終了できるようにしたいということだったので)なので、少しばかりサンプルコード作ってみてみようと思った。
また、今回のケースではDOMを内容を見て何かするというものでなかったので、Processも選択肢になったようだ。
ProcessでIEを操作するという点で色んなサイトを見たけど、少し複雑なことがしたいならCOMを使えという内容がいくつかあったと思う。
それ以外にも、WebBrowser コントロールを使ったり等。
あと、違う記事で書いているけど、ChromiumベースのブラウザCefSharpを使うというのもありだと思う。
今回はIE限定の話だったので、上記のように色々調べたわけです。
ディスカッション
コメント一覧
まだ、コメントがありません