C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: IEコンポーネントによるフレームページへのアクセス


(過去ログ 63 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■36490 / inTopicNo.1)  IEコンポーネントによるフレームページへのアクセス
  
□投稿者/ ヨーキー (1回)-(2009/05/29(Fri) 19:49:50)

分類:[.NET 全般] 

2009/05/29(Fri) 21:07:56 編集(投稿者)
2009/05/29(Fri) 21:06:58 編集(投稿者)
2009/05/29(Fri) 21:06:50 編集(投稿者)
2009/05/29(Fri) 21:06:47 編集(投稿者)

こんばんは。VB初心者ですが、
IEコンポーネントのエラーでどうしても分からないことがあり、質問させて頂きました。

開発環境:VisualBasic2008 Express Edition
OS:windowsXP
ブラウザ:InternetExplorer8(IE7でも同様のエラーを確認)

参照設定:Microsoft HTML Object Library 4.0(COM)
     Microsoft Internet Controls 1.1(COM)

外部起動したIEのフレームページから情報を取得したいく、
下記のようなサンプルコードを作成してテストしているのですが、
IEの起動をBackgroundWorkerから行った場合のみ、@の部分でキャストエラー
(objDoc.framesに対しInvallidCastException)が発生してしまいます。
IEの起動待ち中に処理を止めたくなくて、BackgroundWorkerを使用したいのですが、
どうしてもうまくいかなくて。。。
何か気付くことがありましたら、教えていただけないでしょうか。

−−−−−サンプルコード
Public WithEvents BW As New System.ComponentModel.BackgroundWorker


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Call test() '・・・正常終了
End Sub


Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
BW.RunWorkerAsync() 
End Sub


Private Sub BW_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) _
Handles BW.DoWork
Call test() '・・・@の部分でキャストエラー発生
End Sub


Private Sub test()
Dim objIE As SHDocVw.InternetExplorer

objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
objIE.Navigate("http://jeanne.wankuma.com/")
While (objIE.ReadyState <> 4 Or objIE.Busy = True)
Application.DoEvents()
End While
System.Threading.Thread.Sleep(5000) 'フレーム表示待ち

Dim objDoc As MSHTML.HTMLDocument = objIE.Document
Dim frms As MSHTML.FramesCollection = objDoc.frames '・・・@
Dim frm As MSHTML.HTMLWindow2 = frms.item(1)
Dim frmDoc As MSHTML.HTMLDocument = CType(frms.document, MSHTML.HTMLDocument)

Debug.Print(frmDoc.body.innerText)
End Sub
引用返信 編集キー/
■36498 / inTopicNo.2)  Re[1]: IEコンポーネントによるフレームページへのアクセス
□投稿者/ 渋木宏明(ひどり) (1167回)-(2009/05/29(Fri) 22:00:34)
渋木宏明(ひどり) さんの Web サイト
> IEの起動をBackgroundWorkerから行った場合のみ、@の部分でキャストエラー
> (objDoc.framesに対しInvallidCastException)が発生してしまいます。
> IEの起動待ち中に処理を止めたくなくて、BackgroundWorkerを使用したいのですが、
> どうしてもうまくいかなくて。。。
> 何か気付くことがありましたら、教えていただけないでしょうか。

別スレッドで生成された OLE オートメーションサーバ(およびそのサーバが公開する配下のオブジェクト)の参照に対して、マーシャリングなしで操作を行ったからです。



引用返信 編集キー/
■36499 / inTopicNo.3)  Re[2]: IEコンポーネントによるフレームページへのアクセス
□投稿者/ Hongliang (405回)-(2009/05/29(Fri) 22:07:41)
> 別スレッドで生成された OLE オートメーションサーバ(およびそのサーバが公開する配下のオブジェクト)の参照に対して、マーシャリングなしで操作を行ったからです。

InternetExplroere.Application の生成から一貫して test() メソッド内でやってるんで、それは違うような。
多分処理を行うスレッドのアパートメント状態が STA じゃないからと推測します。
でも BackgroundWorker が使うスレッドはアパートメント状態を設定できないので、そもそも BackgroundWorker では直接使用は不可。
自分で Thread を生成し、SetApartmentState で STA に設定してやる必要があるかな。
引用返信 編集キー/
■36500 / inTopicNo.4)  Re[3]: IEコンポーネントによるフレームページへのアクセス
□投稿者/ Hongliang (406回)-(2009/05/29(Fri) 22:35:22)
それはそれとして、Application.DoEvents は呼び出しちゃダメです。
この場面なら単純に短い Thread.Sleep で十分です。
引用返信 編集キー/
■36505 / inTopicNo.5)  Re[4]: IEコンポーネントによるフレームページへのアクセス
□投稿者/ ヨーキー (3回)-(2009/05/30(Sat) 03:12:43)
ひどりさん、Hongliangさん、ご回答ありがとうございますっ!

>別スレッドで生成された OLE オートメーションサーバ(およびそのサーバが公開する配下のオブジェクト)の参照に対して、マーシャリングなしで操作を行ったからです。

マーシャリングについていろいろ調べて、なんとなくですが理解できた気がします。
マーシャリング=Invokeしてメインスレッドで処理させる と解釈したのですが、
開いているページがAJAXを使用しており、リアルタイム(約1秒間隔)に情報更新される為、
複数のスレッドからそれぞれの情報へ常にアクセスして監視したく、
それをどうマーシャリングすればいいか混乱しております。。。


>InternetExplroere.Application の生成から一貫して test() メソッド内でやってるんで、それは違うような。
>多分処理を行うスレッドのアパートメント状態が STA じゃないからと推測します。
>でも BackgroundWorker が使うスレッドはアパートメント状態を設定できないので、そもそも
BackgroundWorker では直接使用は不可。
>自分で Thread を生成し、SetApartmentState で STA に設定してやる必要があるかな。

ふむふむ。分かったようで分かってないのですが、スレッドをSTAに設定して試してみます〜b

>それはそれとして、Application.DoEvents は呼び出しちゃダメです。
この場面なら単純に短い Thread.Sleep で十分です。

Application.DoEventsってそんなに曲者だったんだ。。。何も分からず使っておりました^^;
ご指摘ありがとうございますっ!

またサンプルコードを作成してトライしてみます!
引用返信 編集キー/
■36510 / inTopicNo.6)  Re[5]: IEコンポーネントによるフレームページへのアクセス
□投稿者/ ヨーキー (5回)-(2009/05/30(Sat) 09:39:40)
こんにちは。教えていただいたことも元にして、下記のサンプルコードを試してみたところ@の部分でのキャストエラーが解消されました。
しっかり理解できているわけではないのですが、COMオブジェクトはメインスレッドのWindowsフォーム(STA)に作成されて、
マーシャリングして使用することにより問題が解決されたのかなと思っております。

COMオブジェクトをBackgroundWorker(別スレッド)から使用した場合、
すべてキャストエラーになるわけではなく、特定のメソッドのみが使えなかったので
windowsの環境の問題なのかと、分からないまま約1カ月くらい悩んでおりました;

自分でThreadを作成し、その中ですべてを処理する方法については、今度テストしてみたいと思います。
キャストエラーは解消されたので、掲示板の方は一旦解決とさせて頂きます。
質問して本当によかったです。ありがとうございましたっ!

'−−−−−サンプルコード
Public WithEvents objIE As SHDocVw.InternetExplorer = Nothing
Public WithEvents BW As New System.ComponentModel.BackgroundWorker
Delegate Sub DelegateTest()


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Call test() '・・・通常の呼び出し
End Sub


Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
BW.RunWorkerAsync()
End Sub


Private Sub BW_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) _
Handles BW.DoWork
Call test() '・・・スレッドからの呼び出し
End Sub


Private Sub test()
If objIE Is Nothing Then
'COMオブジェクトの作成はスレッドからでもOKでした。
objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
objIE.Navigate("http://jeanne.wankuma.com/")
While (objIE.ReadyState <> 4 Or objIE.Busy = True)
System.Threading.Thread.Sleep(100)
End While
System.Threading.Thread.Sleep(5000) 'フレーム表示待ち
End If

If InvokeRequired Then
' 別スレッドから呼び出された場合
Invoke(New DelegateTest(AddressOf test))
Return
End If

Dim objDoc As MSHTML.HTMLDocument = objIE.Document
Dim frms As MSHTML.FramesCollection = objDoc.frames '・・・@(キャストエラー解消)
Dim frm As MSHTML.HTMLWindow2 = frms.item(1)
Dim frmDoc As MSHTML.HTMLDocument = CType(frms.document, MSHTML.HTMLDocument)

Debug.Print(frmDoc.body.innerText)
End Sub
解決済み
引用返信 編集キー/
■36512 / inTopicNo.7)  Re[5]: IEコンポーネントによるフレームページへのアクセス
□投稿者/ 渋木宏明(ひどり) (1168回)-(2009/05/30(Sat) 10:25:17)
渋木宏明(ひどり) さんの Web サイト
>InternetExplroere.Application の生成から一貫して test() メソッド内でやってるんで、それは違うような。
>多分処理を行うスレッドのアパートメント状態が STA じゃないからと推測します。

あー、そうですね。
何も指定しないと MTA だった気がします。

> マーシャリング=Invokeしてメインスレッドで処理させる と解釈したのですが、

違います。

プログラミング方面における「マーシャリング」の意味は、下記参照。

マーシャリング
http://yougo.ascii.jp/caltar/%E3%83%9E%E3%83%BC%E3%82%B7%E3%83%A3%E3%83%AA%E3%83%B3%E3%82%B0

COM/OLE におけるマーシャリングは、アパートメント境界を乗り越えるためのデータ変換を指します。

引用返信 編集キー/
■36514 / inTopicNo.8)  Re[6]: IEコンポーネントによるフレームページへのアクセス
□投稿者/ ヨーキー (6回)-(2009/05/30(Sat) 13:17:43)
> 違います。
>
> プログラミング方面における「マーシャリング」の意味は、下記参照。
>
> マーシャリング
> http://yougo.ascii.jp/caltar/%E3%83%9E%E3%83%BC%E3%82%B7%E3%83%A3%E3%83%AA%E3%83%B3%E3%82%B0
>
> COM/OLE におけるマーシャリングは、アパートメント境界を乗り越えるためのデータ変換を指します。

ご指摘ありがとうございます。
関連記事を関連記事を読み続けておりますが、具体的なコーディングとなると、
わかりそうで分からないです。。。orz

早速で申し訳ありませんが、別スレッド(掲示板)で新たに質問頂きます;
解決済み
引用返信 編集キー/
■36518 / inTopicNo.9)  Re[7]: IEコンポーネントによるフレームページへのアクセス
□投稿者/ 渋木宏明(ひどり) (1170回)-(2009/05/30(Sat) 15:28:37)
渋木宏明(ひどり) さんの Web サイト
> 関連記事を関連記事を読み続けておりますが、具体的なコーディングとなると、
> わかりそうで分からないです。。。orz

僕が挙げた URL は、プログラミング業界における「マーシャリング」の一般的な意味を説明したものです。

COM/OLE におけるマーシャリングについては

http://www.xlsoft.com/jp/products/intel/cvf/docs/vf-html/pg/pg27_05.htm

や、書籍などで勉強してください。

引用返信 編集キー/
■36526 / inTopicNo.10)  Re[8]: IEコンポーネントによるフレームページへのアクセス
□投稿者/ ヨーキー (9回)-(2009/05/30(Sat) 21:28:29)
ご回答ありがとうございますっ!

> COM/OLE におけるマーシャリングについては
>
> http://www.xlsoft.com/jp/products/intel/cvf/docs/vf-html/pg/pg27_05.htm
>
> や、書籍などで勉強してください。

うぅ、やはり理解できてないようです。。。。
リンクして頂いたサイトを読ませていただいたのですが、マーシャリングをすればアパートメントの境界を越えられそう というのは分かったのですが、やはり何をしたらいいかが分かっておりません。。。
出来の悪い子で本当に申し訳ないです;

書籍を購入して、基礎的な部分からじっくり勉強していきたいと思います。

別にスレッド(掲示板)を作ってしまったので、こちらは解決とさせていただきます〜。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -