C#のProcessでIEを複数起動して、すべてのプロセスを閉じる方法
以下記事は以前に書いたCOM経由でIEを操作する方法です。
COMの記事を書いたタイミングでは、-nomergeオプションを使ってなかったのでCOMに変更して対応した。
確か、-noframemergingオプションは試したけど、これはうまくいかなかった。
でも、以下のサンプルコードでやってみると上手くいく。
ということは、後ほど記述するけど、これは起動したIEのx64,x86バージョンの違いによるものかもしれない。
今回の内容は、IE起動の起動と終了をProcess経由でやる方法です。
ただし、いくつか満たすべき条件があります。
満たすべき条件
・64bitのIEを使う必要がある
・-nomergeか-noframemerging オプションの追加が必要
・Windowが立ち上がるまで待つ必要がある。
上記条件を満たして実際に動くソースは以下です。
実験用のソースコード
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()
{
var arg = "https://www.yahoo.co.jp/";
ProcessStartInfo pInfo = new ProcessStartInfo(_iePath, arg);
var p = Process.Start(pInfo);
Thread.Sleep(3000);
p.CloseMainWindow();
}
/// <summary>
/// 複数IEを起動
/// </summary>
public void HandleMultiIE()
{
var arg = "https://www.yahoo.co.jp/";
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()
{
var arg = "-nomerge https://www.yahoo.co.jp/";
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);
}
}
}
}
実験用ソースコードを呼び出す側
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を以下のように呼び出していた。
var p = Process.Start("IExplore.exe", "https://www.yahoo.co.jp/");
これだと私の環境では32bitが呼び出されいるようだった。
恐らくこれも設定で変更可能みたいだけど、特にやってない。
この方法でやるとすると、IE側での設定が必要かもしれないなと、以下の記事を読んでいて思った。
以前書いたサンプル(WinFormで作成)だと例外が発生する
以前書いたサンプルでは、リストに格納されたプロセスに対してCloseMainWindow()すると例外が発生していた。
先ほども書いたけどもう一度。
恐らく32bitが呼び出されていたはず。
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限定の話だったので、上記のように色々調べたわけです。
ディスカッション
コメント一覧
まだ、コメントがありません