ShellExecute 関数で IE を非表示にするには?

解決


kama  2013-10-22 03:21:49  No: 45435

いつもお世話になります。

表題の通りなのですが、IEを非表示で起動できず悩んでいます。
環境は、Delphi XE4, IE Ver.10, Windows7 です。
そのときのコードです。
ShellExecute(Handle, 'open', PChar('IEXPLORE.EXE'), PChar(URL), nil, SW_HIDE);

メモ帳の notepad.exe だと非表示で起動できたのですが・・・。
どうして出来ないのでしょうか?


Harry  2013-10-23 09:35:05  No: 45436

同じ環境がないのと、こちらでは再現しなかったので、参考程度で。
…と、その前に。「IEを非表示で起動」というのは、タスクバーにも表示されない状態ですよね。
なぜそのような動作を必要としているのですか?気になります。

回答にはなってませんが、違うアプローチを。
COMのIEオブジェクトを使って、ゆるーくコントロールするのはどうでしょうか。
動かなかったらゴメンナサイ。

uses
  ComObj;

function WaitIEBusy(IE: OleVariant; Wait: Cardinal): Boolean;
var
  ST: DWORD;
begin
  Result:=False;
  ST:=GetTickCount();
  repeat
    Sleep(100);
    if not IE.Busy then Exit;
  until GetTickCount()-ST>Wait*1000;
  Result:=True;
end;

procedure QuitIE(var IE: OleVariant);
begin
  if VarIsEmpty(IE) then Exit;
  try
    IE.Quit;
  except
    on EOleSysError do; // 多分ユーザーによってIEが閉じられてると判断してスルー
  end;
  IE:=Unassigned;
end;

var
  MyIE: OleVariant;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if not VarIsEmpty(MyIE) then Exit;

  MyIE:=CreateOleObject('InternetExplorer.Application');
//  MyIE.Width:=600;
//  MyIE.Height:=400;
//  MyIE.Toolbar:=False;
//  MyIE.StatusBar:=False;
  MyIE.Visible:=True; // Falseで非表示

  MyIE.Navigate('http://www.google.co.jp/');
  if WaitIEBusy(MyIE, 10) then QuitIE(MyIE); // ナビゲート待ち、10秒でタイムアウト終了
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  QuitIE(MyIE);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  QuitIE(MyIE);
end;


deldel  2013-10-23 19:23:52  No: 45437

win7,D6では非表示で起動しましたが・・・

では、こういうのはどうでしょうか?

  H: HWND;

  ShellExecute(Handle, 'open', PChar('IEXPLORE.EXE'), PChar(URL), nil, SW_HIDE);

  H := FindWindow('IEFrame', nil);

  if H <> 0 then ShowWindow(H, SW_HIDE);


kama  2013-10-25 07:18:09  No: 45438

Harry 様、deldel 様、回答して頂きありがとうございます。

お二方のやり方は初めてだったので勉強になりました。ありがとうございました。・・・ただ、今回は起動直後から非表示になってくれる方法を知りたかったのです・・・。

今更ですが目的は、現在、某サイトのHTMLページからデータを取得してデータベースに保存する、というものを作成していて、IEを操作して自動的に次のページに進むようにしているのですが、そのときIEが表示されるとちょっとカッコ悪いなと思ったので(IE のページが連続で切り替わるのが見えてしまう・・・)、このような質問をさせて頂きました。

一応ですが、あくまでローカルに表示させたHTML形式のデータを、ソースからそのままローカルのDBに保存するだけなので特に違法行為ではない、・・・と思っています。そのページも、ごく一般に公開しているものですし。それにデータベースとHTMLの勉強ついでに作成しているだけなので・・・。


  2013-10-25 08:16:32  No: 45439

ShellExecuteだと、確かに起動はできますが、特定のページへのナビゲートも
うまくできませんし、ナビゲート終了のタイミングを捉えることもできません。
今回のケースでは、Harryさんの提示された手法が適切だと思います。

ちなみに、提示されたコード例に倣うと、MyIE.Visible := Trueを入れない限りは、
望みの動作になるのではないかと思いますが、実際に試されましたか?


3K  2013-10-25 20:01:53  No: 45440

下記でも可?

uses
  ComObj;

procedure TForm1.Button1Click(Sender: TObject);
var
  IExp: Olevariant;
begin
  IExp := CreateOleObject('InternetExplorer.Application');
  IExp.Height := 800;
  IExp.Width := 600;
  IExp.top := 0;
  IExp.Left := 0;  //  -800にすれば見えなくなります
  IExp.Visible := true;
  IExp.Navigate('http://news.livedoor.com/category/vender/80/');
end;

上記で、前にkamaさん希望の動作で株価を取得した記憶が...。


Quest  2013-10-25 21:01:58  No: 45441

「どうしてもIEを使わなくてはいけない」というのではないなら
TWebBrowserを使うというのはいかがでしょう。

やろうと思えばIndyコンポでも何とかなるのではと思います。
面倒でしょうけど(^^;


Harry  2013-10-27 07:40:29  No: 45442

>今回は起動直後から非表示になってくれる方法を知りたかったのです
うーん、コメントの書き方で誤解させちゃいましたかね?
あ さんがフォローしてくれてる通り MyIE.Visible:=True; を削除するか、明示的にFalseにすれば最初から非表示ですよ。

>HTMLページからデータを取得してデータベースに保存する、というものを作成していて、
>IEを操作して自動的に次のページに進むようにしているのですが、そのときIEが表示されると
これは逐次ShellExecuteすることで新しいページに移動させているということですか?
その後どのようにデータを取得しているのでしょうか。まさかキャッシュからソースを取得?

そのようなやり方なら、IEを使わずにUrlMonのURLDownloadToFileというAPI一発で出来てしまいます。
またWinInetには様々なAPIがあり、ファイルに落とさずにダウンロードすることも可能です。

で…、いくつかの案が出ましたが、私はTWebBrowserを非表示で使うことをおすすめします。
IEオブジェクトと違いOnQuitなどのイベントによる支援も受けられ(※1)、型チェックやコード補完も効きます(※2)。
何より、ソースの取得はもちろんのこと、DOM操作によって自在にHTML要素の内容を取得できます(※3)ので。
例:
・ ソースを取得 … VarToStr(Document.documentElement.outerHTML)
・ I番目のAタグリンクを取得 … VarToStr(Document.getElementsByTagName('a').item(I).href)
・ JavaScriptを実行 … Document.parentWindow.execScript('alert("Hello!")')
上記の方法は、JavaScriptやVBScriptのコードが工夫次第でほぼそのまま使えるという利点があります。
ただし、スクリプト的に操作をしているので、タイプミス等があっても実行されるまでエラーは出ません。

※1 →IEオブジェクトでもIEEventsという外部のコンポーネントで一応可能。
※2 →IEオブジェクトもSHDocVwのInternetExplorer(IWebBrowser2)でキャストして使えば可能。
※3 →もちろんIEオブジェクトでも可能ですが。


kama  2013-10-31 00:05:55  No: 45443

アドバイスを下さった皆様、ありがとうございます。
メールを確認できず返信が遅れてしまいました。

TWebBrowser を使用してIE非表示は実現できました。
3K 様のような単純に見えなくしてしまうという方法も気づきませんでした。
Visible = False にすれば読込み時間も短くなるのかと思いコーディングしてみましたが、私の環境だとなぜか Visible = False が効かず表示されっぱなしになってしまいます。なので、Hideプロパティ を使用して非表示にしました。

アドバイス頂きありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加